Bug 15572. Lookup KnownTypeCollection element types in MSSimpleNamespace
[mono.git] / mcs / class / System.ServiceModel.Discovery / System.ServiceModel.Discovery / EndpointDiscoveryMetadata.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Collections.ObjectModel;
4 using System.ServiceModel;
5 using System.ServiceModel.Channels;
6 using System.ServiceModel.Description;
7 using System.ServiceModel.Dispatcher;
8 using System.Xml;
9 using System.Xml.Schema;
10 using System.Xml.Linq;
11
12 namespace System.ServiceModel.Discovery
13 {
14         public class EndpointDiscoveryMetadata
15         {
16                 public static EndpointDiscoveryMetadata FromServiceEndpoint (ServiceEndpoint endpoint)
17                 {
18                         var ret = new EndpointDiscoveryMetadata ();
19                         ret.ContractTypeNames.Add (new XmlQualifiedName (endpoint.Contract.Name, endpoint.Contract.Namespace));
20                         ret.Address = endpoint.Address;
21                         if (endpoint.Address != null)
22                                 ret.ListenUris.Add (endpoint.Address.Uri);
23
24                         var edb = endpoint.Behaviors.Find<EndpointDiscoveryBehavior> ();
25                         if (edb != null) {
26                                 foreach (var ctn in edb.ContractTypeNames)
27                                         ret.ContractTypeNames.Add (ctn);
28                                 foreach (var ext in edb.Extensions)
29                                         ret.Extensions.Add (ext);
30                         }
31
32                         return ret;
33                 }
34
35                 public static EndpointDiscoveryMetadata FromServiceEndpoint (ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
36                 {
37                         throw new NotImplementedException ();
38                 }
39                 
40                 public EndpointDiscoveryMetadata ()
41                 {
42                         Address = new EndpointAddress (EndpointAddress.AnonymousUri);
43                         ContractTypeNames = new Collection<XmlQualifiedName> ();
44                         ListenUris = new Collection<Uri> ();
45                         Scopes = new Collection<Uri> ();
46                         Extensions = new Collection<XElement> ();
47                 }
48
49                 public EndpointAddress Address { get; set; }
50                 public Collection<XmlQualifiedName> ContractTypeNames { get; private set; }
51                 public Collection<XElement> Extensions { get; private set; }
52                 public Collection<Uri> ListenUris { get; private set; }
53                 public Collection<Uri> Scopes { get; private set; }
54                 public int Version { get; set; }
55
56                 internal static EndpointDiscoveryMetadata ReadXml (XmlReader reader, DiscoveryVersion version)
57                 {
58                         if (reader == null)
59                                 throw new ArgumentNullException ("reader");
60
61                         var ret = new EndpointDiscoveryMetadata ();
62
63                         reader.MoveToContent ();
64
65                         reader.ReadStartElement ();
66                         reader.MoveToContent ();
67
68                         // standard members
69                         reader.MoveToContent ();
70
71                         // it is possible due to InternalVisibleToAttribute...
72                         string addrNS = version.MessageVersion.Addressing.Namespace;
73
74                         ret.Address = EndpointAddress.ReadFrom (version.MessageVersion.Addressing, reader, "EndpointReference", addrNS);
75
76                         reader.MoveToContent ();
77                         if (reader.IsStartElement ("Types", version.Namespace))
78                                 ret.ContractTypeNames = new Collection<XmlQualifiedName> ((XmlQualifiedName []) reader.ReadElementContentAs (typeof (XmlQualifiedName []), null, "Types", version.Namespace));
79
80                         reader.MoveToContent ();
81                         if (reader.IsStartElement ("Scopes", version.Namespace))
82                                 ret.Scopes = new Collection<Uri> ((Uri []) reader.ReadElementContentAs (typeof (Uri []), null, "Scopes", version.Namespace));
83
84                         if (reader.IsStartElement ("XAddrs", version.Namespace))
85                                 ret.ListenUris = new Collection<Uri> ((Uri []) reader.ReadElementContentAs (typeof (Uri []), null, "XAddrs", version.Namespace));
86
87                         if (reader.IsStartElement ("MetadataVersion", version.Namespace))
88                                 ret.Version = reader.ReadElementContentAsInt ();
89
90                         // non-standard members
91                         for (reader.MoveToContent (); !reader.EOF && reader.NodeType != XmlNodeType.EndElement; reader.MoveToContent ())
92                                 ret.Extensions.Add (XElement.Load (reader));
93
94                         reader.ReadEndElement ();
95
96                         return ret;
97                 }
98
99                 internal void WriteXml (XmlWriter writer, DiscoveryVersion version)
100                 {
101                         if (writer == null)
102                                 throw new ArgumentNullException ("writer");
103
104                         // standard members
105                         if (Address != null)
106                                 Address.WriteTo (version.MessageVersion.Addressing, writer);
107
108                         writer.WriteStartElement ("d", "Types", version.Namespace);
109                         int p = 0;
110                         foreach (var qname in ContractTypeNames)
111                                 if (writer.LookupPrefix (qname.Namespace) == null)
112                                         writer.WriteAttributeString ("xmlns", "p" + p++, "http://www.w3.org/2000/xmlns/", qname.Namespace);
113                         writer.WriteValue (ContractTypeNames);
114                         writer.WriteEndElement ();
115
116                         if (Scopes.Count > 0) {
117                                 writer.WriteStartElement ("Scopes", version.Namespace);
118                                 writer.WriteValue (Scopes);
119                                 writer.WriteEndElement ();
120                         }
121
122                         if (ListenUris.Count > 0) {
123                                 writer.WriteStartElement ("XAddrs", version.Namespace);
124                                 writer.WriteValue (ListenUris);
125                                 writer.WriteEndElement ();
126                         }
127                         
128                         writer.WriteStartElement ("MetadataVersion", version.Namespace);
129                         writer.WriteValue (Version);
130                         writer.WriteEndElement ();
131
132                         // non-standard members
133
134                         foreach (var ext in Extensions)
135                                 ext.WriteTo (writer);
136                 }
137
138                 internal static XmlSchema BuildSchema (DiscoveryVersion version)
139                 {
140                         var schema = new XmlSchema () { TargetNamespace = version.Namespace };
141
142                         var anyAttr = new XmlSchemaAnyAttribute () { Namespace = "##other", ProcessContents = XmlSchemaContentProcessing.Lax };
143
144                         var probePart = new XmlSchemaSequence ();
145                         probePart.Items.Add (new XmlSchemaElement () { RefName = new XmlQualifiedName ("Types", version.Namespace), MinOccurs = 0 });
146                         probePart.Items.Add (new XmlSchemaElement () { RefName = new XmlQualifiedName ("Scopes", version.Namespace), MinOccurs = 0 });
147                         probePart.Items.Add (new XmlSchemaElement () { RefName = new XmlQualifiedName ("XAddrs", version.Namespace), MinOccurs = 0 });
148                         probePart.Items.Add (new XmlSchemaElement () { RefName = new XmlQualifiedName ("MetadataVersion", version.Namespace), MinOccurs = 0 });
149                         probePart.Items.Add (new XmlSchemaAny () { MinOccurs = 0, MaxOccursString = "unbounded", Namespace = "##other", ProcessContents = XmlSchemaContentProcessing.Lax });
150                         var ct = new XmlSchemaComplexType () { Name = "ProbeMatchType", Particle = probePart, AnyAttribute = anyAttr };
151                         schema.Items.Add (ct);
152
153                         schema.Items.Add (new XmlSchemaSimpleType () { Name = "QNameListType", Content = new XmlSchemaSimpleTypeList () { ItemTypeName = new XmlQualifiedName ("QName", XmlSchema.Namespace) } });
154
155                         var scr = new XmlSchemaSimpleContentRestriction () { BaseTypeName = new XmlQualifiedName ("UriListType", version.Namespace), AnyAttribute = anyAttr };
156                         scr.Attributes.Add (new XmlSchemaAttribute () { Name = "matchBy", SchemaTypeName = new XmlQualifiedName ("anyURI", XmlSchema.Namespace) });
157                         schema.Items.Add (new XmlSchemaComplexType () { Name = "ScopesType", ContentModel = new XmlSchemaSimpleContent () { Content = scr } });
158
159                         schema.Items.Add (new XmlSchemaSimpleType () { Name = "UriListType", Content = new XmlSchemaSimpleTypeList () { ItemTypeName = new XmlQualifiedName ("anyURI", XmlSchema.Namespace) } });
160
161                         schema.Items.Add (new XmlSchemaElement () { Name = "Types", SchemaTypeName = new XmlQualifiedName ("QNameListType", version.Namespace) });
162                         schema.Items.Add (new XmlSchemaElement () { Name = "Scopes", SchemaTypeName = new XmlQualifiedName ("ScopesType", version.Namespace) });
163                         schema.Items.Add (new XmlSchemaElement () { Name = "XAddrs", SchemaTypeName = new XmlQualifiedName ("UriListType", version.Namespace) });
164                         schema.Items.Add (new XmlSchemaElement () { Name = "MetadataVersion", SchemaTypeName = new XmlQualifiedName ("unisgnedInt", XmlSchema.Namespace) });
165
166                         return schema;
167                 }
168         }
169 }