Merge pull request #409 from Alkarex/patch-1
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Description / DataContractSerializerMessageContractImporter.cs
index eb72662f5653294cc3d58c40d9728eee9aed22fc..7b0db9e30855801faecf1c33673bd4e66a691516 100644 (file)
@@ -88,6 +88,8 @@ namespace System.ServiceModel.Description
 
        abstract class MessageContractImporterInternal : IWsdlImportExtension
        {
+               protected abstract void Init (WsdlImporter importer);
+
                public void ImportContract (WsdlImporter importer,
                        WsdlContractConversionContext context)
                {
@@ -98,6 +100,8 @@ namespace System.ServiceModel.Description
                        if (this.importer != null || this.context != null)
                                throw new SystemException ("INTERNAL ERROR: unexpected recursion of ImportContract method call");
 
+                       Init (importer);
+
                        schema_set_in_use = new XmlSchemaSet ();
                        schema_set_in_use.Add (importer.XmlSchemas);
                        foreach (WSDL wsdl in importer.WsdlDocuments)
@@ -116,7 +120,7 @@ namespace System.ServiceModel.Description
                        }
                }
 
-               WsdlImporter importer;
+               internal WsdlImporter importer;
                WsdlContractConversionContext context;
 
                internal XmlSchemaSet schema_set_in_use;
@@ -187,9 +191,18 @@ namespace System.ServiceModel.Description
                bool IsOperationImported (PortType pt, Operation op)
                {
                        foreach (OperationMessage opmsg in op.Messages) {
-                               var parts = context.GetMessageDescription (opmsg).Body.Parts;
-                               foreach (var part in parts)
-                                       if (part.DataContractImporter != null)
+
+                               var opdsc = context.GetMessageDescription (opmsg);
+
+                               var parts = opdsc.Body.Parts;
+                               var ret = opdsc.Body.ReturnValue;
+
+                               if ((ret != null) &&
+                                   (ret.DataContractImporter != null || ret.XmlSerializationImporter != null))
+                                       return true;
+
+                               foreach (var part in opdsc.Body.Parts)
+                                       if (part.DataContractImporter != null || part.XmlSerializationImporter != null)
                                                return true;
                        }
                        return false;
@@ -207,7 +220,8 @@ namespace System.ServiceModel.Description
                                                ResolveType (part.Type, parts, body.WrapperNamespace);
                                        }
                                }
-                               //FIXME: non-parameters?
+                               else
+                                       throw new InvalidOperationException ("Only 'parameters' element in message part is supported"); // this should have been rejected by CanImportOperation().
                        }
                }
 
@@ -227,14 +241,19 @@ namespace System.ServiceModel.Description
 
        class DataContractMessageContractImporterInternal : MessageContractImporterInternal
        {
-               XsdDataContractImporter dc_importer = new XsdDataContractImporter ();
+               XsdDataContractImporter dc_importer;
                
+               protected override void Init (WsdlImporter importer)
+               {
+                       if (dc_importer == null)
+                               dc_importer = importer.GetState<XsdDataContractImporter> ();
+               }
+
                protected override void ImportPartsBySchemaElement (QName qname, List<MessagePartDescription> parts, Message msg, MessagePart part)
                {
                        XmlSchemaElement element = (XmlSchemaElement) schema_set_in_use.GlobalElements [qname];
                        if (element == null)
-                               //FIXME: What to do here?
-                               throw new Exception ("Could not resolve : " + qname.ToString ());
+                               throw new InvalidOperationException ("Could not resolve : " + qname.ToString ()); // this should have been rejected by CanImportOperation().
 
                        var ct = element.ElementSchemaType as XmlSchemaComplexType;
                        if (ct == null) // simple type
@@ -263,7 +282,7 @@ namespace System.ServiceModel.Description
                        part.DataContractImporter = dc_importer;
                        if (dc_importer.CanImport (schema_set_in_use, elem)) {
                                var typeQName = dc_importer.Import (schema_set_in_use, elem);
-                               part.CodeTypeReference = dc_importer.GetCodeTypeReference (typeQName);
+                               part.CodeTypeReference = dc_importer.GetCodeTypeReference (elem.ElementSchemaType.QualifiedName, elem);
                        }
                        return part;
                }
@@ -279,11 +298,32 @@ namespace System.ServiceModel.Description
                        throw new NotImplementedException ();
                }
 
+               Message FindMessage (OperationMessage om)
+               {
+                       foreach (WSDL sd in importer.WsdlDocuments)
+                               if (sd.TargetNamespace == om.Message.Namespace)
+                                       foreach (Message msg in sd.Messages)
+                                               if (msg.Name == om.Message.Name)
+                                                       return msg;
+                       return null;
+               }
+
                protected override bool CanImportOperation (PortType portType, Operation op)
                {
-                       foreach (OperationMessage om in op.Messages)
-                               if (!dc_importer.CanImport (schema_set_in_use, om.Message))
+                       foreach (OperationMessage om in op.Messages) {
+                               var msg = FindMessage (om);
+                               if (msg == null)
                                        return false;
+                               foreach (MessagePart part in msg.Parts) {
+                                       if (part.Name == "parameters" && !part.Element.IsEmpty) {
+                                               var xe = schema_set_in_use.GlobalElements [part.Element] as XmlSchemaElement;
+                                               if (xe == null || !dc_importer.CanImport (schema_set_in_use, xe))
+                                                       return false;
+                                       }
+                                       else
+                                               return false;
+                               }
+                       }
                        return true;
                }
                
@@ -295,7 +335,7 @@ namespace System.ServiceModel.Description
 
        class XmlSerializerMessageContractImporterInternal : MessageContractImporterInternal
        {
-               CodeCompileUnit ccu = new CodeCompileUnit ();
+               CodeCompileUnit ccu;
                XmlSchemaSet schema_set_cache;
                XmlSchemaImporter schema_importer;
                XmlCodeExporter code_exporter;
@@ -303,6 +343,12 @@ namespace System.ServiceModel.Description
                public CodeCompileUnit CodeCompileUnit {
                        get { return ccu; }
                }
+
+               protected override void Init (WsdlImporter importer)
+               {
+                       if (ccu == null)
+                               ccu = importer.GetState<CodeCompileUnit> ();
+               }
                
                protected override void ImportPartsBySchemaElement (QName qname, List<MessagePartDescription> parts, Message msg, MessagePart msgPart)
                {
@@ -326,7 +372,6 @@ namespace System.ServiceModel.Description
                        // FIXME: use of ElementName is a hack!
                        part.CodeTypeReference = new CodeTypeReference (xmm.ElementName);
                        parts.Add (part);
-                       Console.Error.WriteLine ("CodeNamespace {1} in CCU {2} now contains {0} types.", ccu.Namespaces [0].Types.Count, ccu.Namespaces [0].GetHashCode (), ccu.GetHashCode ());
                }
 
                protected override void ResolveType (QName qname, List<MessagePartDescription> parts, string ns)