Ver Fonte

* MessageBinding.cs: Added default value attribute for Name property.
* OperationMessage.cs: Added default value attribute for Name property.
* ServiceDescription.cs: Changed order of some properties, so they are
serialized in the right order.
Added GetNamespaceList(), which returns the namespaces to add when serializing
the document.
Implemented classes ServiceDescriptionSerializer and ServiceDescriptionWriter,
that extends the XmlSerializer by adding suport for XmlFormatExtensions.
* ServiceDescriptionReflector.cs: Basic implementation (no support for
extensions yet).
* SoapBinding.cs: Fixed namespace name.
* SoapBodyBinding.cs: Added null check in PartsString property.
* SoapOperationBinding.cs: Fixed namespace name.

svn path=/trunk/mcs/; revision=17693

Lluis Sanchez há 22 anos atrás
pai
commit
2a90eb61b0

+ 16 - 0
mcs/class/System.Web.Services/System.Web.Services.Description/ChangeLog

@@ -1,3 +1,19 @@
+2003-08-28  Lluis Sanchez Gual  <[email protected]>
+
+	* MessageBinding.cs: Added default value attribute for Name property.
+	* OperationMessage.cs: Added default value attribute for Name property.
+	* ServiceDescription.cs: Changed order of some properties, so they are
+	  serialized in the right order.
+	  Added GetNamespaceList(), which returns the namespaces to add when serializing
+	  the document.
+	  Implemented classes ServiceDescriptionSerializer and ServiceDescriptionWriter,
+	  that extends the XmlSerializer by adding suport for XmlFormatExtensions.
+	* ServiceDescriptionReflector.cs: Basic implementation (no support for 
+	  extensions yet).
+	* SoapBinding.cs: Fixed namespace name.
+	* SoapBodyBinding.cs: Added null check in PartsString property.
+	* SoapOperationBinding.cs: Fixed namespace name.
+	
 2003-07-22  Lluis Sanchez Gual  <[email protected]>
 
 	* Binding.cs, Import.cs, Message.cs, MessageBinding.cs, MessagePart.cs,

+ 3 - 1
mcs/class/System.Web.Services/System.Web.Services.Description/MessageBinding.cs

@@ -7,6 +7,7 @@
 // Copyright (C) Tim Coleman, 2002
 //
 
+using System.ComponentModel;
 using System.Xml.Serialization;
 
 namespace System.Web.Services.Description {
@@ -36,6 +37,7 @@ namespace System.Web.Services.Description {
 			get;
 		}
 
+		[DefaultValue ("")]
 		[XmlAttribute ("name", DataType = "NMTOKEN")]	
 		public string Name {
 			get { return name; }
@@ -49,4 +51,4 @@ namespace System.Web.Services.Description {
 
 		#endregion // Properties
 	}
-}
+}

+ 3 - 1
mcs/class/System.Web.Services/System.Web.Services.Description/OperationMessage.cs

@@ -10,6 +10,7 @@
 using System.Web.Services;
 using System.Xml;
 using System.Xml.Serialization;
+using System.ComponentModel;
 
 namespace System.Web.Services.Description {
 	public abstract class OperationMessage : DocumentableItem {
@@ -41,6 +42,7 @@ namespace System.Web.Services.Description {
 			set { message = value; }
 		}
 
+		[DefaultValue ("")]
 		[XmlAttribute ("name", DataType = "NMTOKEN")]
 		public string Name {
 			get { return name; }
@@ -63,4 +65,4 @@ namespace System.Web.Services.Description {
 
 		#endregion // Methods
 	}
-}
+}

+ 175 - 58
mcs/class/System.Web.Services/System.Web.Services.Description/ServiceDescription.cs

@@ -3,11 +3,14 @@
 //
 // Author:
 //   Tim Coleman ([email protected])
+//   Lluis Sanchez Gual ([email protected])
 //
 // Copyright (C) Tim Coleman, 2002
 //
 
 using System.IO;
+using System.Collections;
+using System.Reflection;
 using System.Web.Services;
 using System.Web.Services.Configuration;
 using System.Xml;
@@ -35,7 +38,6 @@ namespace System.Web.Services.Description {
 		string targetNamespace;
 		Types types;
 		static ServiceDescriptionSerializer serializer;
-		XmlSerializerNamespaces ns;
 
 		#endregion // Fields
 
@@ -60,50 +62,49 @@ namespace System.Web.Services.Description {
 			services = new ServiceCollection (this);
 			targetNamespace = String.Empty;
 			types = null;
-
-			ns = new XmlSerializerNamespaces ();
-			ns.Add ("soap", SoapBinding.Namespace);
-			ns.Add ("s", XmlSchema.Namespace);
-			ns.Add ("http", HttpBinding.Namespace);
-			ns.Add ("mime", MimeContentBinding.Namespace);
-			ns.Add ("tm", MimeTextBinding.Namespace);
 		}
 		
 		#endregion // Constructors
 
 		#region Properties
 
-		[XmlElement ("binding")]
-		public BindingCollection Bindings {
-			get { return bindings; }
-		}
-
-		[XmlIgnore]
-		public ServiceDescriptionFormatExtensionCollection Extensions { 	
-			get { return extensions; }
-		}
-
 		[XmlElement ("import")]
 		public ImportCollection Imports {
 			get { return imports; }
 		}
 
+		[XmlElement ("types")]
+		public Types Types {
+			get { return types; }
+			set { types = value; }
+		}
+
 		[XmlElement ("message")]
 		public MessageCollection Messages {
 			get { return messages; }
 		}
 
+		[XmlElement ("portType")]	
+		public PortTypeCollection PortTypes {
+			get { return portTypes; }
+		}
+	
+		[XmlElement ("binding")]
+		public BindingCollection Bindings {
+			get { return bindings; }
+		}
+
+		[XmlIgnore]
+		public ServiceDescriptionFormatExtensionCollection Extensions { 	
+			get { return extensions; }
+		}
+
 		[XmlAttribute ("name", DataType = "NMTOKEN")]	
 		public string Name {
 			get { return name; }
 			set { name = value; }
 		}
 
-		[XmlElement ("portType")]	
-		public PortTypeCollection PortTypes {
-			get { return portTypes; }
-		}
-	
 		[XmlIgnore]	
 		public string RetrievalUrl {
 			get { return retrievalUrl; }
@@ -135,12 +136,6 @@ namespace System.Web.Services.Description {
 			set { targetNamespace = value; }
 		}
 
-		[XmlElement ("types")]
-		public Types Types {
-			get { return types; }
-			set { types = value; }
-		}
-
 		#endregion // Properties
 
 		#region Methods
@@ -172,8 +167,7 @@ namespace System.Web.Services.Description {
 
 		public void Write (Stream stream)
 		{
-
-			serializer.Serialize (stream, this, ns);
+			serializer.Serialize (stream, this, GetNamespaceList ());
 		}
 
 		public void Write (string fileName)
@@ -183,49 +177,172 @@ namespace System.Web.Services.Description {
 
 		public void Write (TextWriter writer)
 		{
-			serializer.Serialize (writer, this, ns);
+			serializer.Serialize (writer, this, GetNamespaceList ());
 		}
 
 		public void Write (XmlWriter writer)
 		{
-			serializer.Serialize (writer, this, ns);
+			serializer.Serialize (writer, this, GetNamespaceList ());
 		}
 
 		internal void SetParent (ServiceDescriptionCollection serviceDescriptions)
 		{
 			this.serviceDescriptions = serviceDescriptions; 
 		}
-
-		#endregion
-
-		internal class ServiceDescriptionSerializer : XmlSerializer {
-
-			#region Fields
-
+		
+		XmlSerializerNamespaces GetNamespaceList ()
+		{
 			XmlSerializerNamespaces ns;
+			ns = new XmlSerializerNamespaces ();
+			ns.Add ("soap", SoapBinding.Namespace);
+			ns.Add ("s", XmlSchema.Namespace);
+			ns.Add ("http", HttpBinding.Namespace);
+			ns.Add ("mime", MimeContentBinding.Namespace);
+			ns.Add ("tm", MimeTextBinding.Namespace);
+			ns.Add ("s0", TargetNamespace);
+			return ns;
+		}
 
-			#endregion
-
-			#region Constructors
+		#endregion
 
-			[MonoTODO]
-			public ServiceDescriptionSerializer ()
-				: base (typeof (ServiceDescription), ServiceDescription.Namespace)
+		internal class ServiceDescriptionSerializer : XmlSerializer 
+		{
+			static XmlTypeMapping _typeMap;
+			static Type[] _builtinExtensionTypes = new Type[] {
+				typeof (HttpAddressBinding), 
+				typeof (HttpBinding),
+				typeof (HttpOperationBinding),
+				typeof (HttpUrlEncodedBinding),
+				typeof (HttpUrlReplacementBinding),
+				typeof (MimeContentBinding),
+				typeof (MimeMultipartRelatedBinding),
+				typeof (MimePart),
+				typeof (MimeTextBinding),
+				typeof (MimeXmlBinding),
+				typeof (SoapAddressBinding),
+				typeof (SoapBinding),
+				typeof (SoapBodyBinding),
+				typeof (SoapFaultBinding),
+				typeof (SoapHeaderBinding),
+				typeof (SoapHeaderFaultBinding),
+				typeof (SoapOperationBinding)
+			};
+			
+			protected override void Serialize (object o, XmlSerializationWriter writer)
+			{
+				ServiceDescriptionWriter xsWriter = writer as ServiceDescriptionWriter;
+				xsWriter.WriteObject (o);
+			}
+			
+			protected override object Deserialize (XmlSerializationReader reader)
+			{
+				ServiceDescriptionReader xsReader = reader as ServiceDescriptionReader;
+				return xsReader.ReadObject ();
+			}
+			
+			protected override XmlSerializationWriter CreateWriter ()
+			{
+				return new ServiceDescriptionWriter (GetTypeMapping());
+			}
+			
+			protected override XmlSerializationReader CreateReader ()
+			{
+				return new ServiceDescriptionReader (GetTypeMapping());
+			}
+			
+			XmlTypeMapping GetTypeMapping ()
+			{
+				if (_typeMap == null) {
+					XmlReflectionImporter ri = new XmlReflectionImporter (ServiceDescription.Namespace);
+					foreach (Type t in _builtinExtensionTypes) ri.IncludeType (t);
+					_typeMap = ri.ImportTypeMapping (typeof (ServiceDescription));
+				}
+				return _typeMap;
+			}
+		}
+		
+		internal class ServiceDescriptionWriter : XmlSerializationWriterInterpreter
+		{
+			public ServiceDescriptionWriter (XmlMapping typeMap)
+			: base (typeMap)
 			{
-				ns = new XmlSerializerNamespaces ();
-				ns.Add ("soap", SoapBinding.Namespace);
-				ns.Add ("s", XmlSchema.Namespace);
-				ns.Add ("http", HttpBinding.Namespace);
-				ns.Add ("mime", MimeContentBinding.Namespace);
-				ns.Add ("tm", MimeTextBinding.Namespace);
 			}
 
-			#endregion // Constructors
-
-			#region Methods
-
+			protected override void WriteObjectElementElements (XmlTypeMapping typeMap, object ob)
+			{
+				Type type = ob.GetType ();
+				object[] ats = type.GetCustomAttributes (typeof(XmlFormatExtensionPointAttribute), true);
+				if (ats.Length > 0)
+				{
+					XmlFormatExtensionPointAttribute at = (XmlFormatExtensionPointAttribute)ats[0];
+					IEnumerable extensions = null;
+					
+					PropertyInfo prop = type.GetProperty (at.MemberName);
+					if (prop != null)
+						extensions = (IEnumerable) prop.GetValue (ob, null);
+					else {
+						FieldInfo field = type.GetField (at.MemberName);
+						if (field != null)
+							extensions = (IEnumerable) field.GetValue (ob);
+						else
+							throw new InvalidOperationException ("XmlFormatExtensionPointAttribute: Member " + at.MemberName + " not found");
+					}
+					
+					if (extensions != null)
+					{
+						foreach (ServiceDescriptionFormatExtension ext in extensions)
+							WriteExtension (ext);
+					}
+				}
+				
+				base.WriteObjectElementElements (typeMap, ob);
+			}
+			
+			void WriteExtension (ServiceDescriptionFormatExtension ext)
+			{
+				string prefix = null;
+				string ns = null;
+				string name = null;
+				
+				Type type = ext.GetType ();
+				
+				object[] ats = type.GetCustomAttributes (typeof(XmlFormatExtensionPrefixAttribute), true);
+				if (ats.Length > 0)
+				{
+					XmlFormatExtensionPrefixAttribute at = (XmlFormatExtensionPrefixAttribute)ats[0];
+					prefix = at.Prefix;
+					ns = at.Namespace;
+				}
+				
+				ats = type.GetCustomAttributes (typeof(XmlFormatExtensionAttribute), true);
+				if (ats.Length > 0)
+				{
+					XmlFormatExtensionAttribute at = (XmlFormatExtensionAttribute)ats[0];
+					name = at.ElementName;
+					if (at.Namespace != null) ns = at.Namespace;
+				}
+				
+				if (name == null) throw new InvalidOperationException ("XmlFormatExtensionAttribute must be applied to type " + type);
+				
+				if (prefix == null || prefix == "") prefix = Writer.LookupPrefix (ns);
+				
+				if (prefix != null && prefix != "")
+					Writer.WriteStartElement (prefix, name, ns);
+				else
+					WriteStartElement (name, ns, false);
+
+				WriteObjectElement (GetTypeMap (type), ext, name, ns);
+					
+				WriteEndElement ();
+			}
+		}
 
-			#endregion // Methods
+		internal class ServiceDescriptionReader : XmlSerializationReaderInterpreter
+		{
+			public ServiceDescriptionReader (XmlMapping typeMap)
+			: base (typeMap)
+			{
+			}
 		}
 	}
-}
+}

+ 173 - 5
mcs/class/System.Web.Services/System.Web.Services.Description/ServiceDescriptionReflector.cs

@@ -3,20 +3,24 @@
 //
 // Author:
 //   Tim Coleman ([email protected])
+//   Lluis Sanchez Gual ([email protected])
 //
 // Copyright (C) Tim Coleman, 2002
 //
 
 using System.Web.Services;
 using System.Xml.Serialization;
+using System.Xml;
+using System.Web.Services.Protocols;
 
 namespace System.Web.Services.Description {
 	public class ServiceDescriptionReflector {
 
 		#region Fields
 
-		XmlSchemas schemas;
+		Types types;
 		ServiceDescriptionCollection serviceDescriptions;
+		XmlSchemaExporter schemaExporter;
 
 		#endregion // Fields
 
@@ -24,8 +28,9 @@ namespace System.Web.Services.Description {
 	
 		public ServiceDescriptionReflector ()
 		{
-			schemas = new XmlSchemas ();
+			types = new Types ();
 			serviceDescriptions = new ServiceDescriptionCollection ();
+			schemaExporter = new XmlSchemaExporter (types.Schemas);
 		}
 		
 		#endregion // Constructors
@@ -33,7 +38,7 @@ namespace System.Web.Services.Description {
 		#region Properties
 
 		public XmlSchemas Schemas {
-			get { return schemas; }
+			get { return types.Schemas; }
 		}
 
 		public ServiceDescriptionCollection ServiceDescriptions {
@@ -48,9 +53,172 @@ namespace System.Web.Services.Description {
 		[MonoTODO]
 		public void Reflect (Type type, string url)
 		{
-			throw new NotImplementedException ();
+			ServiceDescription desc = new ServiceDescription ();
+			serviceDescriptions.Add (desc);
+			
+			TypeStubInfo typeInfo = TypeStubManager.GetTypeStub (type);
+			desc.TargetNamespace = typeInfo.WebServiceNamespace;
+			desc.Name = typeInfo.WebServiceName;
+			
+			ImportService (desc, typeInfo, url);
+			
+			if (serviceDescriptions.Count == 1)
+				desc.Types = types;
+			else
+			{
+				foreach (ServiceDescription d in serviceDescriptions)
+				{
+					d.Types = new Types();
+					for (int n=0; n<types.Schemas.Count; n++)
+						AddImport (d, types.Schemas[n].TargetNamespace, GetSchemaUrl (url, n));
+				}
+			}
+		}
+		
+		Service ImportService (ServiceDescription desc, TypeStubInfo typeInfo, string url)
+		{
+			Service service = new Service ();
+//			service.Documentation = wsa.Description;
+			service.Name = typeInfo.WebServiceName;
+
+			desc.Services.Add (service);
+			
+			foreach (BindingInfo binfo in typeInfo.Bindings)
+				ImportBinding (desc, service, typeInfo, url, binfo);
+
+			return service;
+		}
+		
+		void ImportBinding (ServiceDescription desc, Service service, TypeStubInfo typeInfo, string url, BindingInfo binfo)
+		{
+			Port port = new Port ();
+			port.Name = binfo.Name;
+			port.Binding = new XmlQualifiedName (binfo.Name, binfo.Namespace);
+			service.Ports.Add (port);
+
+			SoapAddressBinding abind = new SoapAddressBinding ();
+			abind.Location = url;
+			port.Extensions.Add (abind);
+			
+			if (binfo.Namespace != desc.TargetNamespace)
+			{
+				if (binfo.Location == null || binfo.Location == string.Empty)
+				{
+					ServiceDescription newDesc = new ServiceDescription();
+					newDesc.TargetNamespace = binfo.Namespace;
+					int id = serviceDescriptions.Add (newDesc);
+					AddImport (desc, binfo.Namespace, GetWsdlUrl (url,id));
+					ImportBindingContent (newDesc, typeInfo, url, binfo);
+				}
+				else
+					AddImport (desc, binfo.Namespace, binfo.Location);
+			}
+			else
+				ImportBindingContent (desc, typeInfo, url, binfo);
+		}
+		
+		void ImportBindingContent (ServiceDescription desc, TypeStubInfo typeInfo, string url, BindingInfo binfo)
+		{
+			Binding binding = new Binding ();
+			binding.Name = binfo.Name;
+			binding.Type = new XmlQualifiedName (binfo.Name, binfo.Namespace);
+			desc.Bindings.Add (binding);
+			
+			SoapBinding sb = new SoapBinding ();
+			sb.Transport = SoapBinding.HttpTransport;
+			sb.Style = typeInfo.SoapBindingStyle;
+			binding.Extensions.Add (sb);
+			
+			PortType ptype = new PortType ();
+			ptype.Name = binding.Name;
+			desc.PortTypes.Add (ptype);
+
+			foreach (MethodStubInfo method in typeInfo.Methods)
+			{
+				if (method.Binding != binding.Name) continue;
+				
+				Operation oper = ImportOperation (desc, method);
+				ptype.Operations.Add (oper);
+
+				OperationBinding operb = ImportOperationBinding (desc, method);
+				binding.Operations.Add (operb);
+			}
+		}
+		
+		Operation ImportOperation (ServiceDescription desc, MethodStubInfo method)
+		{
+			Operation oper = new Operation ();
+			oper.Name = method.Name;
+			
+			OperationInput inOp = new OperationInput ();
+			inOp.Message = ImportMessage (desc, oper.Name + "In", method.InputMembersMapping);
+			oper.Messages.Add (inOp);
+			
+			OperationOutput outOp = new OperationOutput ();
+			outOp.Message = ImportMessage (desc, oper.Name + "Out", method.OutputMembersMapping);
+			oper.Messages.Add (outOp);
+			
+			return oper;
+		}
+		
+		OperationBinding ImportOperationBinding (ServiceDescription desc, MethodStubInfo method)
+		{
+			OperationBinding oper = new OperationBinding ();
+			oper.Name = method.Name;
+			
+			SoapOperationBinding sob = new SoapOperationBinding();
+			sob.SoapAction = method.Action;
+			sob.Style = method.SoapBindingStyle;
+			oper.Extensions.Add (sob);
+			
+			InputBinding inOp = new InputBinding ();
+			SoapBodyBinding sbbi = new SoapBodyBinding();
+			sbbi.Use = method.Use;
+			inOp.Extensions.Add (sbbi);
+			oper.Input = inOp;
+			
+			OutputBinding outOp = new OutputBinding ();
+			SoapBodyBinding sbbo = new SoapBodyBinding();
+			sbbo.Use = method.Use;
+			outOp.Extensions.Add (sbbo);
+			oper.Output = outOp;
+			
+			return oper;
+		}
+		
+		XmlQualifiedName ImportMessage (ServiceDescription desc, string name, XmlMembersMapping members)
+		{
+			Message msg = new Message ();
+			msg.Name = name;
+			
+			MessagePart part = new MessagePart ();
+			part.Name = "parameters";
+			part.Element = new XmlQualifiedName (members.ElementName, members.Namespace);
+			msg.Parts.Add (part);
+			
+			desc.Messages.Add (msg);
+			schemaExporter.ExportMembersMapping (members);
+			return new XmlQualifiedName (name, members.Namespace);
 		}
 
+		void AddImport (ServiceDescription desc, string ns, string location)
+		{
+			Import im = new Import();
+			im.Namespace = ns;
+			im.Location = location;
+			desc.Imports.Add (im);
+		}
+		
+		string GetWsdlUrl (string baseUrl, int id)
+		{
+			return baseUrl + "?wsdl=" + id;
+		}
+		
+		string GetSchemaUrl (string baseUrl, int id)
+		{
+			return baseUrl + "?schema=" + id;
+		}
+		
 		#endregion
 	}
-}
+}

+ 2 - 2
mcs/class/System.Web.Services/System.Web.Services.Description/SoapBinding.cs

@@ -20,7 +20,7 @@ namespace System.Web.Services.Description {
 
 		#region Fields
 
-		public const string HttpTransport = "http://schemas.xmlsoap.org/soap/http/";
+		public const string HttpTransport = "http://schemas.xmlsoap.org/soap/http";
 		public const string Namespace = "http://schemas.xmlsoap.org/wsdl/soap/";
 
 		SoapBindingStyle style;
@@ -58,4 +58,4 @@ namespace System.Web.Services.Description {
 	
 		#endregion // Properties
 	}
-}
+}

+ 2 - 2
mcs/class/System.Web.Services/System.Web.Services.Description/SoapBodyBinding.cs

@@ -60,7 +60,7 @@ namespace System.Web.Services.Description {
 
 		[XmlAttribute ("parts", DataType = "NMTOKENS")]
 		public string PartsString {
-			get { return String.Join (" ", Parts); }
+			get { return (Parts != null) ? String.Join (" ", Parts) : null; }
 			set { Parts = value.Split (' '); }
 		}
 
@@ -73,4 +73,4 @@ namespace System.Web.Services.Description {
 
 		#endregion // Properties
 	}
-}
+}

+ 2 - 2
mcs/class/System.Web.Services/System.Web.Services.Description/SoapOperationBinding.cs

@@ -12,7 +12,7 @@ using System.Web.Services.Configuration;
 using System.Xml.Serialization;
 
 namespace System.Web.Services.Description {
-	[XmlFormatExtension ("operation", "http://schema.xmlsoap.org/wsdl/soap/", typeof (OperationBinding))]
+	[XmlFormatExtension ("operation", "http://schemas.xmlsoap.org/wsdl/soap/", typeof (OperationBinding))]
 	public sealed class SoapOperationBinding : ServiceDescriptionFormatExtension {
 
 		#region Fields
@@ -53,4 +53,4 @@ namespace System.Web.Services.Description {
 
 		#endregion // Properties
 	}
-}
+}