5 // Lluis Sanchez Gual (lluis@ximian.com)
7 // Copyright (C) 2004 Novel Inc.
13 using System
.Collections
;
14 using System
.Web
.Services
.Description
;
16 using System
.Xml
.Schema
;
17 using System
.Xml
.Serialization
;
19 namespace Mono
.WebServices
21 public class ConsoleSampleGenerator
: SampleGenerator
23 public ConsoleSampleGenerator (ServiceDescriptionCollection services
, XmlSchemas schemas
)
24 : base (services
, schemas
)
28 public static void Generate (ArrayList services
, ArrayList schemas
, string binOper
, string protocol
)
30 ServiceDescriptionCollection descCol
= new ServiceDescriptionCollection ();
31 foreach (ServiceDescription sd
in services
)
36 if (schemas
.Count
> 0) {
37 schemaCol
= new XmlSchemas ();
38 foreach (XmlSchema sc
in schemas
)
42 schemaCol
= descCol
[0].Types
.Schemas
;
44 string oper
, bin
= null;
46 int i
= binOper
.IndexOf ('/');
48 oper
= binOper
.Substring (i
+1);
49 bin
= binOper
.Substring (0,i
);
54 ConsoleSampleGenerator sg
= new ConsoleSampleGenerator (descCol
, schemaCol
);
57 sg
.GenerateMessages (oper
, bin
, protocol
, out req
, out resp
);
60 Console
.WriteLine ("Sample request message:");
62 Console
.WriteLine (req
);
64 Console
.WriteLine ("Sample response message:");
66 Console
.WriteLine (resp
);
69 public void GenerateMessages (string operation
, string bindingName
, string protocol
, out string req
, out string resp
)
71 Port port
= FindPort (bindingName
, protocol
);
72 Binding binding
= descriptions
.GetBinding (port
.Binding
);
73 if (binding
== null) throw new InvalidOperationException ("Binding " + bindingName
+ " not found");
75 PortType portType
= descriptions
.GetPortType (binding
.Type
);
76 Operation oper
= FindOperation (portType
, operation
);
77 if (oper
== null) throw new InvalidOperationException ("Operation " + operation
+ " not found");
78 OperationBinding obin
= FindOperation (binding
, operation
);
80 req
= GenerateMessage (port
, obin
, oper
, protocol
, true);
81 resp
= GenerateMessage (port
, obin
, oper
, protocol
, false);
84 Port
FindPort (string portName
, string protocol
)
86 Service service
= descriptions
[0].Services
[0];
87 foreach (Port port
in service
.Ports
)
91 Binding binding
= descriptions
.GetBinding (port
.Binding
);
92 if (GetProtocol (binding
) == protocol
) return port
;
94 else if (port
.Name
== portName
)
100 string GetProtocol (Binding binding
)
102 if (binding
.Extensions
.Find (typeof(SoapBinding
)) != null) return "Soap";
103 HttpBinding hb
= (HttpBinding
) binding
.Extensions
.Find (typeof(HttpBinding
));
104 if (hb
== null) return "";
105 if (hb
.Verb
== "POST") return "HttpPost";
106 if (hb
.Verb
== "GET") return "HttpGet";
110 Operation
FindOperation (PortType portType
, string name
)
112 foreach (Operation oper
in portType
.Operations
) {
113 if (oper
.Messages
.Input
.Name
!= null) {
114 if (oper
.Messages
.Input
.Name
== name
) return oper
;
117 if (oper
.Name
== name
) return oper
;
123 OperationBinding
FindOperation (Binding binding
, string name
)
125 foreach (OperationBinding oper
in binding
.Operations
) {
126 if (oper
.Input
.Name
!= null) {
127 if (oper
.Input
.Name
== name
) return oper
;
130 if (oper
.Name
== name
) return oper
;
138 // Sample generator class
141 public class SampleGenerator
143 protected ServiceDescriptionCollection descriptions
;
144 protected XmlSchemas schemas
;
145 XmlSchemaElement anyElement
;
147 SoapBindingUse currentUse
;
148 XmlDocument document
= new XmlDocument ();
150 static readonly XmlQualifiedName anyType
= new XmlQualifiedName ("anyType",XmlSchema
.Namespace
);
151 static readonly XmlQualifiedName arrayType
= new XmlQualifiedName ("Array","http://schemas.xmlsoap.org/soap/encoding/");
152 static readonly XmlQualifiedName arrayTypeRefName
= new XmlQualifiedName ("arrayType","http://schemas.xmlsoap.org/soap/encoding/");
153 const string SoapEnvelopeNamespace
= "http://schemas.xmlsoap.org/soap/envelope/";
154 const string WsdlNamespace
= "http://schemas.xmlsoap.org/wsdl/";
155 const string SoapEncodingNamespace
= "http://schemas.xmlsoap.org/soap/encoding/";
159 public EncodedType (string ns
, XmlSchemaElement elem
) { Namespace = ns; Element = elem; }
160 public string Namespace
;
161 public XmlSchemaElement Element
;
164 public SampleGenerator (ServiceDescriptionCollection services
, XmlSchemas schemas
)
166 descriptions
= services
;
167 this.schemas
= schemas
;
168 queue
= new ArrayList ();
171 public string GenerateMessage (Port port
, OperationBinding obin
, Operation oper
, string protocol
, bool generateInput
)
173 OperationMessage msg
= null;
174 foreach (OperationMessage opm
in oper
.Messages
)
176 if (opm
is OperationInput
&& generateInput
) msg
= opm
;
177 else if (opm
is OperationOutput
&& !generateInput
) msg
= opm
;
179 if (msg
== null) return null;
182 case "Soap": return GenerateHttpSoapMessage (port
, obin
, oper
, msg
);
183 case "HttpGet": return GenerateHttpGetMessage (port
, obin
, oper
, msg
);
184 case "HttpPost": return GenerateHttpPostMessage (port
, obin
, oper
, msg
);
186 return "Unknown protocol";
189 public string GenerateHttpSoapMessage (Port port
, OperationBinding obin
, Operation oper
, OperationMessage msg
)
193 if (msg
is OperationInput
)
195 SoapAddressBinding sab
= port
.Extensions
.Find (typeof(SoapAddressBinding
)) as SoapAddressBinding
;
196 SoapOperationBinding sob
= obin
.Extensions
.Find (typeof(SoapOperationBinding
)) as SoapOperationBinding
;
197 req
+= "POST " + new Uri (sab
.Location
).AbsolutePath
+ "\n";
198 req
+= "SOAPAction: " + sob
.SoapAction
+ "\n";
199 req
+= "Content-Type: text/xml; charset=utf-8\n";
200 req
+= "Content-Length: " + GetLiteral ("string") + "\n";
201 req
+= "Host: " + GetLiteral ("string") + "\n\n";
205 req
+= "HTTP/1.0 200 OK\n";
206 req
+= "Content-Type: text/xml; charset=utf-8\n";
207 req
+= "Content-Length: " + GetLiteral ("string") + "\n\n";
210 req
+= GenerateSoapMessage (obin
, oper
, msg
);
214 public string GenerateHttpGetMessage (Port port
, OperationBinding obin
, Operation oper
, OperationMessage msg
)
218 if (msg
is OperationInput
)
220 HttpAddressBinding sab
= port
.Extensions
.Find (typeof(HttpAddressBinding
)) as HttpAddressBinding
;
221 HttpOperationBinding sob
= obin
.Extensions
.Find (typeof(HttpOperationBinding
)) as HttpOperationBinding
;
222 string location
= new Uri (sab
.Location
).AbsolutePath
+ sob
.Location
+ "?" + BuildQueryString (msg
);
223 req
+= "GET " + location
+ "\n";
224 req
+= "Host: " + GetLiteral ("string");
228 req
+= "HTTP/1.0 200 OK\n";
229 req
+= "Content-Type: text/xml; charset=utf-8\n";
230 req
+= "Content-Length: " + GetLiteral ("string") + "\n\n";
232 MimeXmlBinding mxb
= (MimeXmlBinding
) obin
.Output
.Extensions
.Find (typeof(MimeXmlBinding
)) as MimeXmlBinding
;
233 if (mxb
== null) return req
;
235 Message message
= descriptions
.GetMessage (msg
.Message
);
236 XmlQualifiedName ename
= null;
237 foreach (MessagePart part
in message
.Parts
)
238 if (part
.Name
== mxb
.Part
) ename
= part
.Element
;
240 if (ename
== null) return req
+ GetLiteral("string");
242 StringWriter sw
= new StringWriter ();
243 XmlTextWriter xtw
= new XmlTextWriter (sw
);
244 xtw
.Formatting
= Formatting
.Indented
;
245 currentUse
= SoapBindingUse
.Literal
;
246 WriteRootElementSample (xtw
, ename
);
248 req
+= sw
.ToString ();
254 public string GenerateHttpPostMessage (Port port
, OperationBinding obin
, Operation oper
, OperationMessage msg
)
258 if (msg
is OperationInput
)
260 HttpAddressBinding sab
= port
.Extensions
.Find (typeof(HttpAddressBinding
)) as HttpAddressBinding
;
261 HttpOperationBinding sob
= obin
.Extensions
.Find (typeof(HttpOperationBinding
)) as HttpOperationBinding
;
262 string location
= new Uri (sab
.Location
).AbsolutePath
+ sob
.Location
;
263 req
+= "POST " + location
+ "\n";
264 req
+= "Content-Type: application/x-www-form-urlencoded\n";
265 req
+= "Content-Length: " + GetLiteral ("string") + "\n";
266 req
+= "Host: " + GetLiteral ("string") + "\n\n";
267 req
+= BuildQueryString (msg
);
269 else return GenerateHttpGetMessage (port
, obin
, oper
, msg
);
274 string BuildQueryString (OperationMessage opm
)
277 Message msg
= descriptions
.GetMessage (opm
.Message
);
278 foreach (MessagePart part
in msg
.Parts
)
280 if (s
.Length
!= 0) s
+= "&";
281 s
+= part
.Name
+ "=" + GetLiteral (part
.Type
.Name
);
286 public string GenerateSoapMessage (OperationBinding obin
, Operation oper
, OperationMessage msg
)
288 SoapOperationBinding sob
= obin
.Extensions
.Find (typeof(SoapOperationBinding
)) as SoapOperationBinding
;
289 SoapBindingStyle style
= (sob
!= null) ? sob
.Style
: SoapBindingStyle
.Document
;
291 MessageBinding msgbin
= (msg
is OperationInput
) ? (MessageBinding
) obin
.Input
: (MessageBinding
)obin
.Output
;
292 SoapBodyBinding sbb
= msgbin
.Extensions
.Find (typeof(SoapBodyBinding
)) as SoapBodyBinding
;
293 SoapBindingUse bodyUse
= (sbb
!= null) ? sbb
.Use
: SoapBindingUse
.Literal
;
295 StringWriter sw
= new StringWriter ();
296 XmlTextWriter xtw
= new XmlTextWriter (sw
);
297 xtw
.Formatting
= Formatting
.Indented
;
299 xtw
.WriteStartDocument ();
300 xtw
.WriteStartElement ("soap", "Envelope", SoapEnvelopeNamespace
);
301 xtw
.WriteAttributeString ("xmlns", "xsi", null, XmlSchema
.InstanceNamespace
);
302 xtw
.WriteAttributeString ("xmlns", "xsd", null, XmlSchema
.Namespace
);
304 if (bodyUse
== SoapBindingUse
.Encoded
)
306 xtw
.WriteAttributeString ("xmlns", "soapenc", null, SoapEncodingNamespace
);
307 xtw
.WriteAttributeString ("xmlns", "tns", null, msg
.Message
.Namespace
);
312 bool writtenHeader
= false;
313 foreach (object ob
in msgbin
.Extensions
)
315 SoapHeaderBinding hb
= ob
as SoapHeaderBinding
;
316 if (hb
== null) continue;
318 if (!writtenHeader
) {
319 xtw
.WriteStartElement ("soap", "Header", SoapEnvelopeNamespace
);
320 writtenHeader
= true;
323 WriteHeader (xtw
, hb
);
327 xtw
.WriteEndElement ();
330 xtw
.WriteStartElement ("soap", "Body", SoapEnvelopeNamespace
);
332 currentUse
= bodyUse
;
333 WriteBody (xtw
, oper
, msg
, sbb
, style
);
335 xtw
.WriteEndElement ();
336 xtw
.WriteEndElement ();
338 return sw
.ToString ();
341 void WriteHeader (XmlTextWriter xtw
, SoapHeaderBinding header
)
343 Message msg
= descriptions
.GetMessage (header
.Message
);
344 if (msg
== null) throw new InvalidOperationException ("Message " + header
.Message
+ " not found");
345 MessagePart part
= msg
.Parts
[header
.Part
];
346 if (part
== null) throw new InvalidOperationException ("Message part " + header
.Part
+ " not found in message " + header
.Message
);
348 currentUse
= header
.Use
;
350 if (currentUse
== SoapBindingUse
.Literal
)
351 WriteRootElementSample (xtw
, part
.Element
);
353 WriteTypeSample (xtw
, part
.Type
);
356 void WriteBody (XmlTextWriter xtw
, Operation oper
, OperationMessage opm
, SoapBodyBinding sbb
, SoapBindingStyle style
)
358 Message msg
= descriptions
.GetMessage (opm
.Message
);
359 if (msg
.Parts
.Count
> 0 && msg
.Parts
[0].Name
== "parameters")
361 MessagePart part
= msg
.Parts
[0];
362 if (part
.Element
== XmlQualifiedName
.Empty
)
363 WriteTypeSample (xtw
, part
.Type
);
365 WriteRootElementSample (xtw
, part
.Element
);
369 string elemName
= oper
.Name
;
371 if (opm
is OperationOutput
) elemName
+= "Response";
373 if (style
== SoapBindingStyle
.Rpc
) {
374 xtw
.WriteStartElement (elemName
, sbb
.Namespace
);
378 foreach (MessagePart part
in msg
.Parts
)
380 if (part
.Element
== XmlQualifiedName
.Empty
)
382 XmlSchemaElement elem
= new XmlSchemaElement ();
383 elem
.SchemaTypeName
= part
.Type
;
384 elem
.Name
= part
.Name
;
385 WriteElementSample (xtw
, ns
, elem
);
388 WriteRootElementSample (xtw
, part
.Element
);
391 if (style
== SoapBindingStyle
.Rpc
)
392 xtw
.WriteEndElement ();
394 WriteQueuedTypeSamples (xtw
);
397 void WriteRootElementSample (XmlTextWriter xtw
, XmlQualifiedName qname
)
399 XmlSchemaElement elem
= (XmlSchemaElement
) schemas
.Find (qname
, typeof(XmlSchemaElement
));
400 if (elem
== null) throw new InvalidOperationException ("Element not found: " + qname
);
401 WriteElementSample (xtw
, qname
.Namespace
, elem
);
404 void WriteElementSample (XmlTextWriter xtw
, string ns
, XmlSchemaElement elem
)
406 bool sharedAnnType
= false;
407 XmlQualifiedName root
;
409 if (!elem
.RefName
.IsEmpty
) {
410 XmlSchemaElement refElem
= FindRefElement (elem
);
411 if (refElem
== null) throw new InvalidOperationException ("Global element not found: " + elem
.RefName
);
414 sharedAnnType
= true;
417 root
= new XmlQualifiedName (elem
.Name
, ns
);
419 if (!elem
.SchemaTypeName
.IsEmpty
)
421 XmlSchemaComplexType st
= FindComplexTyype (elem
.SchemaTypeName
);
423 WriteComplexTypeSample (xtw
, st
, root
);
426 xtw
.WriteStartElement (root
.Name
, root
.Namespace
);
427 if (currentUse
== SoapBindingUse
.Encoded
)
428 xtw
.WriteAttributeString ("type", XmlSchema
.InstanceNamespace
, GetQualifiedNameString (xtw
, elem
.SchemaTypeName
));
429 xtw
.WriteString (GetLiteral (FindBuiltInType (elem
.SchemaTypeName
)));
430 xtw
.WriteEndElement ();
433 else if (elem
.SchemaType
== null)
435 xtw
.WriteStartElement ("any");
436 xtw
.WriteEndElement ();
439 WriteComplexTypeSample (xtw
, (XmlSchemaComplexType
) elem
.SchemaType
, root
);
442 void WriteTypeSample (XmlTextWriter xtw
, XmlQualifiedName qname
)
444 XmlSchemaComplexType ctype
= FindComplexTyype (qname
);
446 WriteComplexTypeSample (xtw
, ctype
, qname
);
450 XmlSchemaSimpleType stype
= (XmlSchemaSimpleType
) schemas
.Find (qname
, typeof(XmlSchemaSimpleType
));
452 WriteSimpleTypeSample (xtw
, stype
);
456 xtw
.WriteString (GetLiteral (FindBuiltInType (qname
)));
457 throw new InvalidOperationException ("Type not found: " + qname
);
460 void WriteComplexTypeSample (XmlTextWriter xtw
, XmlSchemaComplexType stype
, XmlQualifiedName rootName
)
462 WriteComplexTypeSample (xtw
, stype
, rootName
, -1);
465 void WriteComplexTypeSample (XmlTextWriter xtw
, XmlSchemaComplexType stype
, XmlQualifiedName rootName
, int id
)
467 string ns
= rootName
.Namespace
;
469 if (rootName
.Name
.IndexOf ("[]") != -1) rootName
= arrayType
;
471 if (currentUse
== SoapBindingUse
.Encoded
) {
472 string pref
= xtw
.LookupPrefix (rootName
.Namespace
);
473 if (pref
== null) pref
= "q1";
474 xtw
.WriteStartElement (pref
, rootName
.Name
, rootName
.Namespace
);
478 xtw
.WriteStartElement (rootName
.Name
, rootName
.Namespace
);
482 xtw
.WriteAttributeString ("id", "id" + id
);
483 if (rootName
!= arrayType
)
484 xtw
.WriteAttributeString ("type", XmlSchema
.InstanceNamespace
, GetQualifiedNameString (xtw
, rootName
));
487 WriteComplexTypeAttributes (xtw
, stype
);
488 WriteComplexTypeElements (xtw
, ns
, stype
);
490 xtw
.WriteEndElement ();
493 void WriteComplexTypeAttributes (XmlTextWriter xtw
, XmlSchemaComplexType stype
)
495 WriteAttributes (xtw
, stype
.Attributes
, stype
.AnyAttribute
);
498 void WriteComplexTypeElements (XmlTextWriter xtw
, string ns
, XmlSchemaComplexType stype
)
500 if (stype
.Particle
!= null)
501 WriteParticleComplexContent (xtw
, ns
, stype
.Particle
);
504 if (stype
.ContentModel
is XmlSchemaSimpleContent
)
505 WriteSimpleContent (xtw
, (XmlSchemaSimpleContent
)stype
.ContentModel
);
506 else if (stype
.ContentModel
is XmlSchemaComplexContent
)
507 WriteComplexContent (xtw
, ns
, (XmlSchemaComplexContent
)stype
.ContentModel
);
511 void WriteAttributes (XmlTextWriter xtw
, XmlSchemaObjectCollection atts
, XmlSchemaAnyAttribute anyat
)
513 foreach (XmlSchemaObject at
in atts
)
515 if (at
is XmlSchemaAttribute
)
518 XmlSchemaAttribute attr
= (XmlSchemaAttribute
)at
;
519 XmlSchemaAttribute refAttr
= attr
;
521 // refAttr.Form; TODO
523 if (!attr
.RefName
.IsEmpty
) {
524 refAttr
= FindRefAttribute (attr
.RefName
);
525 if (refAttr
== null) throw new InvalidOperationException ("Global attribute not found: " + attr
.RefName
);
529 if (!refAttr
.SchemaTypeName
.IsEmpty
) val
= FindBuiltInType (refAttr
.SchemaTypeName
);
530 else val
= FindBuiltInType ((XmlSchemaSimpleType
) refAttr
.SchemaType
);
532 xtw
.WriteAttributeString (refAttr
.Name
, val
);
534 else if (at
is XmlSchemaAttributeGroupRef
)
536 XmlSchemaAttributeGroupRef gref
= (XmlSchemaAttributeGroupRef
)at
;
537 XmlSchemaAttributeGroup grp
= (XmlSchemaAttributeGroup
) schemas
.Find (gref
.RefName
, typeof(XmlSchemaAttributeGroup
));
538 WriteAttributes (xtw
, grp
.Attributes
, grp
.AnyAttribute
);
543 xtw
.WriteAttributeString ("custom-attribute","value");
546 void WriteParticleComplexContent (XmlTextWriter xtw
, string ns
, XmlSchemaParticle particle
)
548 WriteParticleContent (xtw
, ns
, particle
, false);
551 void WriteParticleContent (XmlTextWriter xtw
, string ns
, XmlSchemaParticle particle
, bool multiValue
)
553 if (particle
is XmlSchemaGroupRef
)
554 particle
= GetRefGroupParticle ((XmlSchemaGroupRef
)particle
);
556 if (particle
.MaxOccurs
> 1) multiValue
= true;
558 if (particle
is XmlSchemaSequence
) {
559 WriteSequenceContent (xtw
, ns
, ((XmlSchemaSequence
)particle
).Items
, multiValue
);
561 else if (particle
is XmlSchemaChoice
) {
562 if (((XmlSchemaChoice
)particle
).Items
.Count
== 1)
563 WriteSequenceContent (xtw
, ns
, ((XmlSchemaChoice
)particle
).Items
, multiValue
);
565 WriteChoiceContent (xtw
, ns
, (XmlSchemaChoice
)particle
, multiValue
);
567 else if (particle
is XmlSchemaAll
) {
568 WriteSequenceContent (xtw
, ns
, ((XmlSchemaAll
)particle
).Items
, multiValue
);
572 void WriteSequenceContent (XmlTextWriter xtw
, string ns
, XmlSchemaObjectCollection items
, bool multiValue
)
574 foreach (XmlSchemaObject item
in items
)
575 WriteContentItem (xtw
, ns
, item
, multiValue
);
578 void WriteContentItem (XmlTextWriter xtw
, string ns
, XmlSchemaObject item
, bool multiValue
)
580 if (item
is XmlSchemaGroupRef
)
581 item
= GetRefGroupParticle ((XmlSchemaGroupRef
)item
);
583 if (item
is XmlSchemaElement
)
585 XmlSchemaElement elem
= (XmlSchemaElement
) item
;
586 XmlSchemaElement refElem
;
587 if (!elem
.RefName
.IsEmpty
) refElem
= FindRefElement (elem
);
590 int num
= (elem
.MaxOccurs
== 1 && !multiValue
) ? 1 : 2;
591 for (int n
=0; n
<num
; n
++)
593 if (currentUse
== SoapBindingUse
.Literal
)
594 WriteElementSample (xtw
, ns
, refElem
);
596 WriteRefTypeSample (xtw
, ns
, refElem
);
599 else if (item
is XmlSchemaAny
)
601 xtw
.WriteString (GetLiteral ("xml"));
603 else if (item
is XmlSchemaParticle
) {
604 WriteParticleContent (xtw
, ns
, (XmlSchemaParticle
)item
, multiValue
);
608 void WriteChoiceContent (XmlTextWriter xtw
, string ns
, XmlSchemaChoice choice
, bool multiValue
)
610 foreach (XmlSchemaObject item
in choice
.Items
)
611 WriteContentItem (xtw
, ns
, item
, multiValue
);
614 void WriteSimpleContent (XmlTextWriter xtw
, XmlSchemaSimpleContent content
)
616 XmlSchemaSimpleContentExtension ext
= content
.Content
as XmlSchemaSimpleContentExtension
;
618 WriteAttributes (xtw
, ext
.Attributes
, ext
.AnyAttribute
);
620 XmlQualifiedName qname
= GetContentBaseType (content
.Content
);
621 xtw
.WriteString (GetLiteral (FindBuiltInType (qname
)));
624 string FindBuiltInType (XmlQualifiedName qname
)
626 if (qname
.Namespace
== XmlSchema
.Namespace
)
629 XmlSchemaComplexType ct
= FindComplexTyype (qname
);
632 XmlSchemaSimpleContent sc
= ct
.ContentModel
as XmlSchemaSimpleContent
;
633 if (sc
== null) throw new InvalidOperationException ("Invalid schema");
634 return FindBuiltInType (GetContentBaseType (sc
.Content
));
637 XmlSchemaSimpleType st
= (XmlSchemaSimpleType
) schemas
.Find (qname
, typeof(XmlSchemaSimpleType
));
639 return FindBuiltInType (st
);
641 throw new InvalidOperationException ("Definition of type " + qname
+ " not found");
644 string FindBuiltInType (XmlSchemaSimpleType st
)
646 if (st
.Content
is XmlSchemaSimpleTypeRestriction
) {
647 return FindBuiltInType (GetContentBaseType (st
.Content
));
649 else if (st
.Content
is XmlSchemaSimpleTypeList
) {
650 string s
= FindBuiltInType (GetContentBaseType (st
.Content
));
651 return s
+ " " + s
+ " ...";
653 else if (st
.Content
is XmlSchemaSimpleTypeUnion
)
655 // Check if all types of the union are equal. If not, then will use anyType.
656 XmlSchemaSimpleTypeUnion uni
= (XmlSchemaSimpleTypeUnion
) st
.Content
;
659 // Anonymous types are unique
660 if (uni
.BaseTypes
.Count
!= 0 && uni
.MemberTypes
.Length
!= 0)
663 foreach (XmlQualifiedName mt
in uni
.MemberTypes
)
665 string qn
= FindBuiltInType (mt
);
666 if (utype
!= null && qn
!= utype
) return "string";
676 XmlQualifiedName
GetContentBaseType (XmlSchemaObject ob
)
678 if (ob
is XmlSchemaSimpleContentExtension
)
679 return ((XmlSchemaSimpleContentExtension
)ob
).BaseTypeName
;
680 else if (ob
is XmlSchemaSimpleContentRestriction
)
681 return ((XmlSchemaSimpleContentRestriction
)ob
).BaseTypeName
;
682 else if (ob
is XmlSchemaSimpleTypeRestriction
)
683 return ((XmlSchemaSimpleTypeRestriction
)ob
).BaseTypeName
;
684 else if (ob
is XmlSchemaSimpleTypeList
)
685 return ((XmlSchemaSimpleTypeList
)ob
).ItemTypeName
;
690 void WriteComplexContent (XmlTextWriter xtw
, string ns
, XmlSchemaComplexContent content
)
692 XmlQualifiedName qname
;
694 XmlSchemaComplexContentExtension ext
= content
.Content
as XmlSchemaComplexContentExtension
;
695 if (ext
!= null) qname
= ext
.BaseTypeName
;
697 XmlSchemaComplexContentRestriction rest
= (XmlSchemaComplexContentRestriction
)content
.Content
;
698 qname
= rest
.BaseTypeName
;
699 if (qname
== arrayType
) {
700 ParseArrayType (rest
, out qname
);
701 XmlSchemaElement elem
= new XmlSchemaElement ();
703 elem
.SchemaTypeName
= qname
;
705 xtw
.WriteAttributeString ("arrayType", SoapEncodingNamespace
, qname
.Name
+ "[2]");
706 WriteContentItem (xtw
, ns
, elem
, true);
711 // Add base map members to this map
712 XmlSchemaComplexType ctype
= FindComplexTyype (qname
);
713 WriteComplexTypeAttributes (xtw
, ctype
);
716 // Add the members of this map
717 WriteAttributes (xtw
, ext
.Attributes
, ext
.AnyAttribute
);
718 if (ext
.Particle
!= null)
719 WriteParticleComplexContent (xtw
, ns
, ext
.Particle
);
722 WriteComplexTypeElements (xtw
, ns
, ctype
);
725 void ParseArrayType (XmlSchemaComplexContentRestriction rest
, out XmlQualifiedName qtype
)
727 XmlSchemaAttribute arrayTypeAt
= FindArrayAttribute (rest
.Attributes
);
728 XmlAttribute
[] uatts
= arrayTypeAt
.UnhandledAttributes
;
729 if (uatts
== null || uatts
.Length
== 0) throw new InvalidOperationException ("arrayType attribute not specified in array declaration");
731 XmlAttribute xat
= null;
732 foreach (XmlAttribute at
in uatts
)
733 if (at
.LocalName
== "arrayType" && at
.NamespaceURI
== WsdlNamespace
)
737 throw new InvalidOperationException ("arrayType attribute not specified in array declaration");
739 string arrayType
= xat
.Value
;
741 int i
= arrayType
.LastIndexOf (":");
742 if (i
== -1) ns
= "";
743 else ns
= arrayType
.Substring (0,i
);
745 int j
= arrayType
.IndexOf ("[", i
+1);
746 if (j
== -1) throw new InvalidOperationException ("Cannot parse WSDL array type: " + arrayType
);
747 type
= arrayType
.Substring (i
+1);
748 type
= type
.Substring (0, type
.Length
-2);
750 qtype
= new XmlQualifiedName (type
, ns
);
753 XmlSchemaAttribute
FindArrayAttribute (XmlSchemaObjectCollection atts
)
755 foreach (object ob
in atts
)
757 XmlSchemaAttribute att
= ob
as XmlSchemaAttribute
;
758 if (att
!= null && att
.RefName
== arrayTypeRefName
) return att
;
760 XmlSchemaAttributeGroupRef gref
= ob
as XmlSchemaAttributeGroupRef
;
763 XmlSchemaAttributeGroup grp
= (XmlSchemaAttributeGroup
) schemas
.Find (gref
.RefName
, typeof(XmlSchemaAttributeGroup
));
764 att
= FindArrayAttribute (grp
.Attributes
);
765 if (att
!= null) return att
;
771 void WriteSimpleTypeSample (XmlTextWriter xtw
, XmlSchemaSimpleType stype
)
773 xtw
.WriteString (GetLiteral (FindBuiltInType (stype
)));
776 XmlSchemaParticle
GetRefGroupParticle (XmlSchemaGroupRef refGroup
)
778 XmlSchemaGroup grp
= (XmlSchemaGroup
) schemas
.Find (refGroup
.RefName
, typeof (XmlSchemaGroup
));
782 XmlSchemaElement
FindRefElement (XmlSchemaElement elem
)
784 if (elem
.RefName
.Namespace
== XmlSchema
.Namespace
)
786 if (anyElement
!= null) return anyElement
;
787 anyElement
= new XmlSchemaElement ();
788 anyElement
.Name
= "any";
789 anyElement
.SchemaTypeName
= anyType
;
792 return (XmlSchemaElement
) schemas
.Find (elem
.RefName
, typeof(XmlSchemaElement
));
795 XmlSchemaAttribute
FindRefAttribute (XmlQualifiedName refName
)
797 if (refName
.Namespace
== XmlSchema
.Namespace
)
799 XmlSchemaAttribute at
= new XmlSchemaAttribute ();
800 at
.Name
= refName
.Name
;
801 at
.SchemaTypeName
= new XmlQualifiedName ("string",XmlSchema
.Namespace
);
804 return (XmlSchemaAttribute
) schemas
.Find (refName
, typeof(XmlSchemaAttribute
));
807 void WriteRefTypeSample (XmlTextWriter xtw
, string ns
, XmlSchemaElement elem
)
809 if (elem
.SchemaTypeName
.Namespace
== XmlSchema
.Namespace
|| schemas
.Find (elem
.SchemaTypeName
, typeof(XmlSchemaSimpleType
)) != null)
810 WriteElementSample (xtw
, ns
, elem
);
813 xtw
.WriteStartElement (elem
.Name
, ns
);
814 xtw
.WriteAttributeString ("href", "#id" + (queue
.Count
+1));
815 xtw
.WriteEndElement ();
816 queue
.Add (new EncodedType (ns
, elem
));
820 void WriteQueuedTypeSamples (XmlTextWriter xtw
)
822 for (int n
=0; n
<queue
.Count
; n
++)
824 EncodedType ec
= (EncodedType
) queue
[n
];
825 XmlSchemaComplexType st
= FindComplexTyype (ec
.Element
.SchemaTypeName
);
826 WriteComplexTypeSample (xtw
, st
, ec
.Element
.SchemaTypeName
, n
+1);
830 XmlSchemaComplexType
FindComplexTyype (XmlQualifiedName qname
)
832 if (qname
.Name
.IndexOf ("[]") != -1)
834 XmlSchemaComplexType stype
= new XmlSchemaComplexType ();
835 stype
.ContentModel
= new XmlSchemaComplexContent ();
837 XmlSchemaComplexContentRestriction res
= new XmlSchemaComplexContentRestriction ();
838 stype
.ContentModel
.Content
= res
;
839 res
.BaseTypeName
= arrayType
;
841 XmlSchemaAttribute att
= new XmlSchemaAttribute ();
842 att
.RefName
= arrayTypeRefName
;
843 res
.Attributes
.Add (att
);
845 XmlAttribute xat
= document
.CreateAttribute ("arrayType", WsdlNamespace
);
846 xat
.Value
= qname
.Namespace
+ ":" + qname
.Name
;
847 att
.UnhandledAttributes
= new XmlAttribute
[] {xat}
;
851 return (XmlSchemaComplexType
) schemas
.Find (qname
, typeof(XmlSchemaComplexType
));
854 string GetQualifiedNameString (XmlTextWriter xtw
, XmlQualifiedName qname
)
856 string pref
= xtw
.LookupPrefix (qname
.Namespace
);
857 if (pref
!= null) return pref
+ ":" + qname
.Name
;
859 xtw
.WriteAttributeString ("xmlns", "q1", null, qname
.Namespace
);
860 return "q1:" + qname
.Name
;
863 protected virtual string GetLiteral (string s
)
868 void GetOperationFormat (OperationBinding obin
, out SoapBindingStyle style
, out SoapBindingUse use
)
870 style
= SoapBindingStyle
.Document
;
871 use
= SoapBindingUse
.Literal
;
872 SoapOperationBinding sob
= obin
.Extensions
.Find (typeof(SoapOperationBinding
)) as SoapOperationBinding
;
875 SoapBodyBinding sbb
= obin
.Input
.Extensions
.Find (typeof(SoapBodyBinding
)) as SoapBodyBinding
;