2009-08-07 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel / EndpointAddress.cs
1 //
2 // System.ServiceModel.EndpointAddress.cs
3 //
4 // Author: Duncan Mak (duncan@novell.com)
5 //         Atsushi Enomoto (atsushi@ximian.com)
6 //
7 // Copyright (C) 2005-2006 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System;
30 using System.IO;
31 using System.Reflection;
32 using System.Resources;
33 using System.Runtime.Serialization;
34 using System.Security.Cryptography.X509Certificates;
35 using System.Xml;
36 using System.Xml.Schema;
37 using System.Xml.Serialization;
38 using System.ServiceModel.Channels;
39 using System.ServiceModel.Description;
40
41 namespace System.ServiceModel
42 {
43         public class EndpointAddress
44         {
45                 static readonly Uri w3c_anonymous = new Uri (Constants.WsaAnonymousUri);
46                 static readonly Uri anonymous_role = new Uri ("http://schemas.microsoft.com/2005/12/ServiceModel/Addressing/Anonymous");
47                 static readonly Uri none_role = new Uri ("http://schemas.microsoft.com/2005/12/ServiceModel/Addressing/None");
48
49                 public static Uri AnonymousUri {
50                         get { return anonymous_role; }
51                 }
52
53                 public static Uri NoneUri {
54                         get { return none_role; }
55                 }
56
57                 Uri address;
58                 AddressHeaderCollection headers;
59                 EndpointIdentity identity;
60                 XmlDictionaryReader metadata_reader;
61                 XmlDictionaryReader extension_reader;
62
63                 static XmlSchema schema;
64
65                 public EndpointAddress (string uri)
66                         : this (new Uri (uri), new AddressHeader [0])
67                 {
68                 }
69
70                 public EndpointAddress (Uri uri, params AddressHeader [] headers)
71                         : this (uri, null, new AddressHeaderCollection (headers), null, null) {}
72
73                 public EndpointAddress (Uri uri, EndpointIdentity identity, params AddressHeader [] headers)
74                         : this (uri, identity, new AddressHeaderCollection (headers), null, null) {}
75
76                 public EndpointAddress (Uri uri, EndpointIdentity identity, AddressHeaderCollection headers)
77                         : this (uri, identity, headers, null, null) {}
78
79                 public EndpointAddress (
80                         Uri uri, EndpointIdentity identity,
81                         AddressHeaderCollection headers,
82                         XmlDictionaryReader metadataReader,
83                         XmlDictionaryReader extensionReader)
84                 {       
85                         if (uri == null)
86                                 throw new ArgumentNullException ("uri");
87                         if (!uri.IsAbsoluteUri)
88                                 throw new ArgumentException ("The argument uri must be absolute");
89                         this.address = uri;
90                         this.identity = identity;
91                         this.headers = headers;
92                         metadata_reader = metadataReader;
93                         extension_reader = extensionReader;
94                 }
95
96                 public bool IsAnonymous {
97                         get { return address.Equals (anonymous_role); }
98                 }
99
100                 public bool IsNone {
101                         get { return address.Equals (none_role); }
102                 }
103
104                 public AddressHeaderCollection Headers {
105                         get { return headers; }
106                 }
107
108                 public EndpointIdentity Identity {
109                         get { return identity; }
110                 }
111
112                 public Uri Uri {
113                         get { return address; }
114                 }
115
116 #if !NET_2_1
117                 internal static XmlSchema Schema {
118                         get {
119                                 if (schema == null) {
120                                         Assembly a = Assembly.GetCallingAssembly ();
121                                         Stream s = a.GetManifestResourceStream ("WS-Addressing.schema");
122                                         schema = XmlSchema.Read (s, null);
123                                 }
124
125                                 return schema;
126                         }
127                 }
128 #endif
129
130                 [MonoTODO]
131                 public void ApplyTo (Message message)
132                 {
133                         throw new NotImplementedException ();
134                 }
135
136                 public override bool Equals (object obj)
137                 {
138                         EndpointAddress other = obj as EndpointAddress;
139                         if (other == null || 
140                             other.Uri == null || !other.Uri.Equals (this.Uri) ||
141                             other.Headers.Count != this.Headers.Count)
142                                 return false;
143
144                         foreach (AddressHeader h in this.Headers) {
145                                 bool match = false;
146                                 foreach (AddressHeader o in other.Headers)
147                                         if (h.Equals (o)) {
148                                                 match = true;
149                                                 break;
150                                         }
151                                 if (!match)
152                                         return false;
153                         }
154
155                         return true;
156                 }
157
158                 public override int GetHashCode ()
159                 {
160                         return address.GetHashCode ();
161                 }
162
163                 public XmlDictionaryReader GetReaderAtExtensions ()
164                 {
165                         return extension_reader;
166                 }
167
168                 public XmlDictionaryReader GetReaderAtMetadata ()
169                 {
170                         return metadata_reader;
171                 }
172
173                 public static bool operator == (EndpointAddress address1, EndpointAddress address2)
174                 {
175                         if ((object) address1 == null)
176                                 return (object) address2 == null;
177                         if ((object) address2 == null)
178                                 return false;
179                         return address1.Equals (address2);
180                 }
181
182                 public static bool operator != (EndpointAddress address1, EndpointAddress address2)
183                 {
184                         return ! (address1 == address2);
185                 }
186
187 #if !NET_2_1
188                 [MonoTODO]
189                 public static EndpointAddress ReadFrom (
190                         XmlDictionaryReader reader)
191                 {
192                         if (reader == null)
193                                 throw new ArgumentNullException ("reader");
194
195                         return ReadFromInternal (null, reader);
196                 }
197
198                 [MonoTODO]
199                 public static EndpointAddress ReadFrom (
200                         AddressingVersion addressingVersion,
201                         XmlDictionaryReader reader)
202                 {
203                         return ReadFrom (addressingVersion, (XmlReader) reader);
204                 }
205
206                 [MonoTODO]
207                 public static EndpointAddress ReadFrom (
208                         AddressingVersion addressingVersion,
209                         XmlReader reader)
210                 {
211                         if (addressingVersion == null)
212                                 throw new ArgumentNullException ("addressingVersion");
213                         if (reader == null)
214                                 throw new ArgumentNullException ("reader");
215
216                         return ReadFromInternal (addressingVersion, reader);
217                 }
218
219                 [MonoTODO]
220                 public static EndpointAddress ReadFrom (
221                         XmlDictionaryReader reader,
222                         XmlDictionaryString localName,
223                         XmlDictionaryString ns)
224                 {
225                         return ReadFrom (AddressingVersion.WSAddressing10,
226                                          reader, localName, ns);
227                 }
228
229
230                 [MonoTODO]
231                 public static EndpointAddress ReadFrom (
232                         AddressingVersion addressingVersion,
233                         XmlDictionaryReader reader,
234                         XmlDictionaryString localName,
235                         XmlDictionaryString ns)
236                 {
237                         throw new NotImplementedException ();
238                 }
239
240                 [MonoTODO]
241                 public static EndpointAddress ReadFrom (
242                         AddressingVersion addressingVersion,
243                         XmlReader reader, string localname, string ns)
244                 {
245                         throw new NotImplementedException ();
246                 }
247
248                 private static EndpointAddress ReadFromInternal (
249                         AddressingVersion addressingVersion,
250                         XmlReader reader)
251                 {
252                         reader.MoveToContent ();
253                         if (reader.NodeType != XmlNodeType.Element ||
254                             reader.IsEmptyElement)
255                                 throw new ArgumentException ("Cannot detect appropriate WS-Addressing Address element.");
256
257                         reader.Read ();
258                         reader.MoveToContent ();
259
260                         if (addressingVersion == null) {
261                                 if (reader.NamespaceURI == AddressingVersion.WSAddressing10.Namespace)
262                                         addressingVersion = AddressingVersion.WSAddressing10;
263                                 else
264                                 if (reader.NamespaceURI == AddressingVersion.WSAddressingAugust2004.Namespace)
265                                         addressingVersion = AddressingVersion.WSAddressingAugust2004;
266                                 else
267                                         throw new ArgumentException ("Cannot detect appropriate WS-Addressing version.");
268                         }
269
270                         EndpointAddress ea = ReadContents (addressingVersion, reader);
271
272                         reader.MoveToContent ();
273                         reader.ReadEndElement ();
274                         return ea;
275                 }
276                 
277                 private static EndpointAddress ReadContents (
278                         AddressingVersion addressingVersion, XmlReader reader)
279                 {
280                         Uri uri = null;
281                         MetadataSet metadata = null;
282                         EndpointIdentity identity = null;
283                         reader.MoveToContent ();
284                         if (reader.LocalName == "Address" && 
285                             reader.NamespaceURI == addressingVersion.Namespace &&
286                             reader.NodeType == XmlNodeType.Element &&
287                             !reader.IsEmptyElement)
288                                 uri = new Uri (reader.ReadElementContentAsString ());
289                         else
290                                 throw new XmlException (String.Format (
291                                         "Expecting 'Address' from namespace '{0}', but found '{1}' from namespace '{2}'",
292                                         addressingVersion.Namespace, reader.LocalName, reader.NamespaceURI));
293
294                         reader.MoveToContent ();
295                         if (reader.LocalName == "Metadata" &&
296                             reader.NamespaceURI == addressingVersion.Namespace &&
297                             !reader.IsEmptyElement) {
298                                 reader.Read ();
299                                 metadata = (MetadataSet) new XmlSerializer (typeof (MetadataSet)).Deserialize (reader);
300                                 reader.MoveToContent ();
301                                 reader.ReadEndElement ();
302                         }
303                         reader.MoveToContent ();
304                         if (reader.LocalName == "Identity" &&
305                             reader.NamespaceURI == Constants.WsaIdentityUri) {
306                                 // FIXME: implement
307                                 reader.Skip ();
308                         }
309
310                         if (addressingVersion == AddressingVersion.WSAddressing10 && uri == w3c_anonymous)
311                                 uri = anonymous_role;
312
313                         if (metadata == null)
314                                 return new EndpointAddress (uri, identity);
315                         return new EndpointAddress (uri, identity,
316                                 AddressHeader.CreateAddressHeader (metadata));
317                 }
318 #endif
319
320                 public override string ToString ()
321                 {
322                         return address.ToString (); 
323                 }
324
325                 [MonoTODO]
326                 public void WriteContentsTo (
327                         AddressingVersion addressingVersion,
328                         XmlDictionaryWriter writer)
329                 {
330 #if NET_2_1
331                         writer.WriteString (Uri.AbsoluteUri);
332 #else
333                         if (addressingVersion == AddressingVersion.WSAddressing10) {
334                                 ((IXmlSerializable) EndpointAddress10.FromEndpointAddress (this)).WriteXml (writer);
335                         } else {
336                                 writer.WriteString (Uri.AbsoluteUri);
337                         }
338 #endif
339                 }
340
341                 public void WriteContentsTo (
342                         AddressingVersion addressingVersion,
343                         XmlWriter writer)
344                 {
345                         WriteContentsTo (addressingVersion,
346                                 XmlDictionaryWriter.CreateDictionaryWriter (writer));
347                 }
348
349                 public void WriteTo (
350                         AddressingVersion addressingVersion,
351                         XmlDictionaryWriter writer)
352                 {
353                         WriteTo (addressingVersion, writer, "EndpointReference", addressingVersion.Namespace);
354                 }
355
356                 public void WriteTo (
357                         AddressingVersion addressingVersion, XmlWriter writer)
358                 {
359                         WriteTo (addressingVersion,
360                                 XmlDictionaryWriter.CreateDictionaryWriter (writer));
361                 }
362
363                 public void WriteTo (
364                         AddressingVersion addressingVersion,
365                         XmlDictionaryWriter writer,
366                         XmlDictionaryString localname,
367                         XmlDictionaryString ns)
368                 {
369                         writer.WriteStartElement (localname, ns);
370                         WriteContentsTo (addressingVersion, writer);
371                         writer.WriteEndElement ();
372                 }
373
374                 public void WriteTo (
375                         AddressingVersion addressingVersion,
376                         XmlWriter writer, string localname, string ns)
377                 {
378                         writer.WriteStartElement (localname, ns);
379                         WriteContentsTo (addressingVersion, writer);
380                         writer.WriteEndElement ();
381                 }
382         }
383 }