EndpointDiscoveryMetadata.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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. namespace System.ServiceModel.Discovery
  12. {
  13. public class EndpointDiscoveryMetadata
  14. {
  15. public static EndpointDiscoveryMetadata FromServiceEndpoint (ServiceEndpoint endpoint)
  16. {
  17. var ret = new EndpointDiscoveryMetadata ();
  18. ret.ContractTypeNames.Add (new XmlQualifiedName (endpoint.Contract.Name, endpoint.Contract.Namespace));
  19. ret.Address = endpoint.Address;
  20. if (endpoint.Address != null)
  21. ret.ListenUris.Add (endpoint.Address.Uri);
  22. var edb = endpoint.Behaviors.Find<EndpointDiscoveryBehavior> ();
  23. if (edb != null) {
  24. foreach (var ctn in edb.ContractTypeNames)
  25. ret.ContractTypeNames.Add (ctn);
  26. foreach (var ext in edb.Extensions)
  27. ret.Extensions.Add (ext);
  28. }
  29. return ret;
  30. }
  31. public static EndpointDiscoveryMetadata FromServiceEndpoint (ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
  32. {
  33. throw new NotImplementedException ();
  34. }
  35. public EndpointDiscoveryMetadata ()
  36. {
  37. Address = new EndpointAddress (EndpointAddress.AnonymousUri);
  38. ContractTypeNames = new Collection<XmlQualifiedName> ();
  39. ListenUris = new Collection<Uri> ();
  40. Scopes = new Collection<Uri> ();
  41. Extensions = new Collection<XElement> ();
  42. }
  43. public EndpointAddress Address { get; set; }
  44. public Collection<XmlQualifiedName> ContractTypeNames { get; private set; }
  45. public Collection<XElement> Extensions { get; private set; }
  46. public Collection<Uri> ListenUris { get; private set; }
  47. public Collection<Uri> Scopes { get; private set; }
  48. public int Version { get; set; }
  49. const string addrNS = "http://www.w3.org/2005/08/addressing";
  50. internal static EndpointDiscoveryMetadata ReadXml (XmlReader reader, DiscoveryVersion version)
  51. {
  52. if (reader == null)
  53. throw new ArgumentNullException ("reader");
  54. var ret = new EndpointDiscoveryMetadata ();
  55. reader.MoveToContent ();
  56. reader.ReadStartElement ();
  57. reader.MoveToContent ();
  58. // standard members
  59. reader.MoveToContent ();
  60. ret.Address = EndpointAddress.ReadFrom (AddressingVersion.WSAddressing10, reader, "EndpointReference", addrNS);
  61. reader.MoveToContent ();
  62. if (reader.IsStartElement ("Types", version.Namespace))
  63. ret.ContractTypeNames = new Collection<XmlQualifiedName> ((XmlQualifiedName []) reader.ReadElementContentAs (typeof (XmlQualifiedName []), null, "Types", version.Namespace));
  64. reader.MoveToContent ();
  65. if (reader.IsStartElement ("Scopes", version.Namespace))
  66. ret.Scopes = new Collection<Uri> ((Uri []) reader.ReadElementContentAs (typeof (Uri []), null, "Scopes", version.Namespace));
  67. if (reader.IsStartElement ("XAddrs", version.Namespace))
  68. ret.ListenUris = new Collection<Uri> ((Uri []) reader.ReadElementContentAs (typeof (Uri []), null, "XAddrs", version.Namespace));
  69. if (reader.IsStartElement ("MetadataVersion", version.Namespace))
  70. ret.Version = reader.ReadElementContentAsInt ();
  71. // non-standard members
  72. for (reader.MoveToContent (); !reader.EOF && reader.NodeType != XmlNodeType.EndElement; reader.MoveToContent ())
  73. ret.Extensions.Add (XElement.Load (reader));
  74. reader.ReadEndElement ();
  75. return ret;
  76. }
  77. internal void WriteXml (XmlWriter writer, DiscoveryVersion version)
  78. {
  79. if (writer == null)
  80. throw new ArgumentNullException ("writer");
  81. // standard members
  82. if (Address != null)
  83. Address.WriteTo (AddressingVersion.WSAddressing10, writer);
  84. writer.WriteStartElement ("d", "Types", version.Namespace);
  85. int p = 0;
  86. foreach (var qname in ContractTypeNames)
  87. if (writer.LookupPrefix (qname.Namespace) == null)
  88. writer.WriteAttributeString ("xmlns", "p" + p++, "http://www.w3.org/2000/xmlns/", qname.Namespace);
  89. writer.WriteValue (ContractTypeNames);
  90. writer.WriteEndElement ();
  91. if (Scopes.Count > 0) {
  92. writer.WriteStartElement ("Scopes", version.Namespace);
  93. writer.WriteValue (Scopes);
  94. writer.WriteEndElement ();
  95. }
  96. if (ListenUris.Count > 0) {
  97. writer.WriteStartElement ("XAddrs", version.Namespace);
  98. writer.WriteValue (ListenUris);
  99. writer.WriteEndElement ();
  100. }
  101. writer.WriteStartElement ("MetadataVersion", version.Namespace);
  102. writer.WriteValue (Version);
  103. writer.WriteEndElement ();
  104. // non-standard members
  105. foreach (var ext in Extensions)
  106. ext.WriteTo (writer);
  107. }
  108. internal static XmlSchema BuildSchema (DiscoveryVersion version)
  109. {
  110. var schema = new XmlSchema () { TargetNamespace = version.Namespace };
  111. var anyAttr = new XmlSchemaAnyAttribute () { Namespace = "##other", ProcessContents = XmlSchemaContentProcessing.Lax };
  112. var probePart = new XmlSchemaSequence ();
  113. probePart.Items.Add (new XmlSchemaElement () { RefName = new XmlQualifiedName ("Types", version.Namespace), MinOccurs = 0 });
  114. probePart.Items.Add (new XmlSchemaElement () { RefName = new XmlQualifiedName ("Scopes", version.Namespace), MinOccurs = 0 });
  115. probePart.Items.Add (new XmlSchemaElement () { RefName = new XmlQualifiedName ("XAddrs", version.Namespace), MinOccurs = 0 });
  116. probePart.Items.Add (new XmlSchemaElement () { RefName = new XmlQualifiedName ("MetadataVersion", version.Namespace), MinOccurs = 0 });
  117. probePart.Items.Add (new XmlSchemaAny () { MinOccurs = 0, MaxOccursString = "unbounded", Namespace = "##other", ProcessContents = XmlSchemaContentProcessing.Lax });
  118. var ct = new XmlSchemaComplexType () { Name = "ProbeMatchType", Particle = probePart, AnyAttribute = anyAttr };
  119. schema.Items.Add (ct);
  120. schema.Items.Add (new XmlSchemaSimpleType () { Name = "QNameListType", Content = new XmlSchemaSimpleTypeList () { ItemTypeName = new XmlQualifiedName ("QName", XmlSchema.Namespace) } });
  121. var scr = new XmlSchemaSimpleContentRestriction () { BaseTypeName = new XmlQualifiedName ("UriListType", version.Namespace), AnyAttribute = anyAttr };
  122. scr.Attributes.Add (new XmlSchemaAttribute () { Name = "matchBy", SchemaTypeName = new XmlQualifiedName ("anyURI", XmlSchema.Namespace) });
  123. schema.Items.Add (new XmlSchemaComplexType () { Name = "ScopesType", ContentModel = new XmlSchemaSimpleContent () { Content = scr } });
  124. schema.Items.Add (new XmlSchemaSimpleType () { Name = "UriListType", Content = new XmlSchemaSimpleTypeList () { ItemTypeName = new XmlQualifiedName ("anyURI", XmlSchema.Namespace) } });
  125. schema.Items.Add (new XmlSchemaElement () { Name = "Types", SchemaTypeName = new XmlQualifiedName ("QNameListType", version.Namespace) });
  126. schema.Items.Add (new XmlSchemaElement () { Name = "Scopes", SchemaTypeName = new XmlQualifiedName ("ScopesType", version.Namespace) });
  127. schema.Items.Add (new XmlSchemaElement () { Name = "XAddrs", SchemaTypeName = new XmlQualifiedName ("UriListType", version.Namespace) });
  128. schema.Items.Add (new XmlSchemaElement () { Name = "MetadataVersion", SchemaTypeName = new XmlQualifiedName ("unisgnedInt", XmlSchema.Namespace) });
  129. return schema;
  130. }
  131. }
  132. }