2010-02-19 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Fri, 19 Feb 2010 04:50:07 +0000 (04:50 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Fri, 19 Feb 2010 04:50:07 +0000 (04:50 -0000)
* ServiceContractGenerator.cs, MessagePartDescription.cs,
  DataContractSerializerMessageContractImporter.cs :
  add alternative implementation to use XsdDataContractImporter
  instead of XmlSchemaImporter hack.

  It requires -d:USE_DATA_CONTRACT_IMPORTER and not enabled yet, as
  it breaks some WSDL imports (such as memorabilia.hardrock.com).

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

mcs/class/System.ServiceModel/System.ServiceModel.Description/ChangeLog
mcs/class/System.ServiceModel/System.ServiceModel.Description/DataContractSerializerMessageContractImporter.cs
mcs/class/System.ServiceModel/System.ServiceModel.Description/MessagePartDescription.cs
mcs/class/System.ServiceModel/System.ServiceModel.Description/ServiceContractGenerator.cs

index ba1414f448d10c601d41775ad3605991b8166b64..6ad0e9c94aa5d11f8b07fd8821a2c761c38e1a07 100644 (file)
@@ -1,3 +1,13 @@
+2010-02-19  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ServiceContractGenerator.cs, MessagePartDescription.cs,
+         DataContractSerializerMessageContractImporter.cs :
+         add alternative implementation to use XsdDataContractImporter
+         instead of XmlSchemaImporter hack.
+
+         It requires -d:USE_DATA_CONTRACT_IMPORTER and not enabled yet, as
+         it breaks some WSDL imports (such as memorabilia.hardrock.com).
+
 2010-02-11  Atsushi Enomoto  <atsushi@ximian.com>
 
        * DataContractSerializerMessageContractImporter.cs : handle duration
index 4f7a5a9d01dea2528738d2b141e6500f76751a18..d17b4135d5977a101a5ae95e4d6cca11f346b86a 100644 (file)
@@ -28,6 +28,7 @@
 using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
+using System.Runtime.Serialization;
 using System.ServiceModel;
 using System.Text;
 using System.Web.Services.Description;
@@ -71,6 +72,11 @@ namespace System.ServiceModel.Description
                        if (this.importer != null || this.context != null)
                                throw new SystemException ("INTERNAL ERROR: unexpected recursion of ImportContract method call");
 
+#if USE_DATA_CONTRACT_IMPORTER
+                       dc_importer = new XsdDataContractImporter ();
+                       dc_importer.Import (importer.XmlSchemas);
+#endif
+
                        this.importer = importer;
                        this.context = context;
                        try {
@@ -83,6 +89,10 @@ namespace System.ServiceModel.Description
 
                WsdlImporter importer;
                WsdlContractConversionContext context;
+
+               XsdDataContractImporter dc_importer;
+
+#if !USE_DATA_CONTRACT_IMPORTER
                XmlSchemaImporter schema_importer_;
                XmlSchemaImporter schema_importer {
                        get {
@@ -112,6 +122,7 @@ namespace System.ServiceModel.Description
                                return xml_schemas_;
                        }
                }
+#endif
 
                void DoImportContract ()
                {
@@ -179,15 +190,29 @@ namespace System.ServiceModel.Description
                        }
                }
                
+#if USE_DATA_CONTRACT_IMPORTER
                void resolveElement (QName qname, List<MessagePartDescription> parts, string ns)
                {
-                       XmlSchemaElement element = (XmlSchemaElement) xml_schemas.Find (qname, typeof (XmlSchemaElement));
+                       XmlSchemaElement element = (XmlSchemaElement) importer.XmlSchemas.GlobalElements [qname];
                        if (element == null)
                                //FIXME: What to do here?
                                throw new Exception ("Could not resolve : " + qname.ToString ());
 
+                       var msg_part = new MessagePartDescription (qname.Name, qname.Namespace);
+                       msg_part.Importer = dc_importer;
+                       msg_part.CodeTypeReference = dc_importer.GetCodeTypeReference (dc_importer.Import (importer.XmlSchemas, element));
+                       parts.Add (msg_part);
+               }
+#else
+               void resolveElement (QName qname, List<MessagePartDescription> parts, string ns)
+               {
+                       XmlSchemaElement element = (XmlSchemaElement) xml_schemas.Find (qname, typeof (XmlSchemaElement));
+                       if (element == null)
+                               //FIXME: What to do here?
+                               throw new Exception ("Could not resolve : " + qname.ToString ());
                        resolveParticle (schema_importer, element, parts, ns, 2);
                }
+#endif
 
                void resolveType (QName qname, List<MessagePartDescription> parts, string ns)
                {
@@ -262,6 +287,7 @@ namespace System.ServiceModel.Description
                        return null;
                }
 
+#if !USE_DATA_CONTRACT_IMPORTER
                void resolveParticle (XmlSchemaImporter schema_importer, 
                                XmlSchemaParticle particle, 
                                List<MessagePartDescription> parts, 
@@ -318,6 +344,7 @@ namespace System.ServiceModel.Description
 
                        parts.Add (msg_part);
                }
+#endif
 
                void IWsdlImportExtension.ImportEndpoint (WsdlImporter importer,
                        WsdlEndpointConversionContext context)
index ecda62bcc05bb48eb375ba51fb966749de2b7046..324ef74670b9abffdc843bccca7b3d519a919a7b 100644 (file)
@@ -94,6 +94,11 @@ namespace System.ServiceModel.Description
                        set { type = value; }
                }
 
+#if !NET_2_1
+#if USE_DATA_CONTRACT_IMPORTER
+               internal XsdDataContractImporter Importer { get; set; }
+               internal System.CodeDom.CodeTypeReference CodeTypeReference { get; set; }
+#else
                internal XmlQualifiedName TypeName {
                        get { return xml_schema_type_name; }
                        set { xml_schema_type_name = value; }
@@ -103,6 +108,7 @@ namespace System.ServiceModel.Description
                        get { return xml_type_mapping; }
                        set { xml_type_mapping = value; }
                }
-
+#endif
+#endif
        }
 }
index f4cecfc4ca9a9c7de308ad35b33da78378f0aa81..f14b7b5f0b942de5b052e81de29348b05b9bdbed 100644 (file)
@@ -62,6 +62,8 @@ namespace System.ServiceModel.Description
                ServiceContractGenerationContext contract_context;
                List<OPair> operation_contexts = new List<OPair> ();
 
+               XsdDataContractImporter xsd_data_importer;
+
                public ServiceContractGenerator ()
                        : this (null, null)
                {
@@ -150,6 +152,9 @@ namespace System.ServiceModel.Description
                        if ((Options & ServiceContractGenerationOptions.ClientClass) != 0)
                                GenerateProxyClass (contractDescription, cns);
 
+                       if (xsd_data_importer != null)
+                               MergeCompileUnit (xsd_data_importer.CodeCompileUnit, ccu);
+
                        // Process extensions. Class first, then methods.
                        // (built-in ones must present before processing class extensions).
                        foreach (var cb in contractDescription.Behaviors) {
@@ -718,8 +723,12 @@ namespace System.ServiceModel.Description
                        foreach (MessageDescription md in messages) {
                                if (md.Direction == MessageDirection.Output) {
                                        if (md.Body.ReturnValue != null) {
-                                               ExportDataContract (md.Body.ReturnValue.XmlTypeMapping);        
+                                               ExportDataContract (md.Body.ReturnValue);
+#if USE_DATA_CONTRACT_IMPORTER
+                                               method.ReturnType = md.Body.ReturnValue.CodeTypeReference;
+#else
                                                method.ReturnType = new CodeTypeReference (GetCodeTypeName (md.Body.ReturnValue.TypeName));
+#endif
                                        }
                                        continue;
                                }
@@ -729,11 +738,15 @@ namespace System.ServiceModel.Description
 
                                MessagePartDescriptionCollection parts = md.Body.Parts;
                                for (int i = 0; i < parts.Count; i++) {
-                                       ExportDataContract (parts [i].XmlTypeMapping);  
+                                       ExportDataContract (parts [i]);
 
                                        method.Parameters.Add (
                                                new CodeParameterDeclarationExpression (
+#if USE_DATA_CONTRACT_IMPORTER
+                                                       parts [i].CodeTypeReference,
+#else
                                                        new CodeTypeReference (GetCodeTypeName (parts [i].TypeName)),
+#endif
                                                        parts [i].Name));
 
                                        if (return_args)
@@ -754,8 +767,44 @@ namespace System.ServiceModel.Description
                        throw new NotImplementedException ();
                }
 
-               private void ExportDataContract (XmlTypeMapping mapping)
+#if USE_DATA_CONTRACT_IMPORTER
+               void MergeCompileUnit (CodeCompileUnit from, CodeCompileUnit to)
+               {
+                       foreach (CodeNamespace fns in from.Namespaces) {
+                               foreach (CodeNamespace tns in to.Namespaces)
+                                       if (fns.Name == tns.Name) {
+                                               // namespaces are merged.
+                                               MergeNamespace (fns, tns);
+                                               continue;
+                                       }
+                               to.Namespaces.Add (fns);
+                       }
+               }
+
+               // existing type is skipped.
+               void MergeNamespace (CodeNamespace from, CodeNamespace to)
                {
+                       foreach (CodeTypeDeclaration ftd in from.Types) {
+                               bool skip = false;
+                               foreach (CodeTypeDeclaration ttd in to.Types)
+                                       if (ftd.Name == ttd.Name) {
+                                               skip = true;
+                                               break;
+                                       }
+                               if (!skip)
+                                       to.Types.Add (ftd);
+                       }
+               }
+#endif
+
+               private void ExportDataContract (MessagePartDescription md)
+               {
+#if USE_DATA_CONTRACT_IMPORTER
+                       if (xsd_data_importer == null)
+                               xsd_data_importer = md.Importer;
+#else
+                       var mapping = md.XmlTypeMapping;
+
                        if (mapping == null)
                                return;
 
@@ -862,6 +911,7 @@ namespace System.ServiceModel.Description
                                cns.Types.Remove (type);
 
                        ccu.Namespaces.Add (cns);
+#endif
                }
                
                private string GetXmlNamespace (CodeTypeDeclaration type)