2010-02-22 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Description / MetadataExchangeClient.cs
1 //
2 // MetadataExchangeClient.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //      Ankit Jain <jankit@novell.com>
7 //
8 // Copyright (C) 2005 Novell, Inc.  http://www.novell.com
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29 using System;
30 using System.Collections.Generic;
31 using System.Collections.ObjectModel;
32 using System.ServiceModel;
33 using System.ServiceModel.Channels;
34 using System.ServiceModel.Description;
35 using System.Web.Services.Description;
36 using System.Web.Services.Discovery;
37 using System.Web.Services.Protocols;
38 using System.Xml;
39 using System.Xml.Serialization;
40 using System.IO;
41 using System.Net;
42 using System.Text;
43
44 using SMBinding = System.ServiceModel.Channels.Binding;
45 using SMMessage = System.ServiceModel.Channels.Message;
46
47 namespace System.ServiceModel.Description
48 {
49         [MonoTODO ("MetadataExchangeClientMode is not considered")]
50         public class MetadataExchangeClient
51         {
52                 string scheme;
53
54                 EndpointAddress address;
55                 SMBinding binding;
56                 MetadataExchangeClientMode mode = MetadataExchangeClientMode.MetadataExchange;
57
58                 // constructors
59
60                 [MonoTODO ("use empty configuration")]
61                 public MetadataExchangeClient ()
62                 {
63                 }
64
65                 public MetadataExchangeClient (SMBinding mexBinding)
66                 {
67                         binding = mexBinding;
68                 }
69
70                 public MetadataExchangeClient (EndpointAddress address)
71                 {
72                         this.address = address;
73                 }
74
75                 public MetadataExchangeClient (string endpointConfigurationName)
76                 {
77                         throw new NotImplementedException ();
78                 }
79
80                 public MetadataExchangeClient (Uri address, MetadataExchangeClientMode mode)
81                 {
82                         this.address = new EndpointAddress (address.AbsoluteUri);
83                         this.mode = mode;
84                 }
85
86                 // sync methods
87
88                 public MetadataSet GetMetadata ()
89                 {
90                         return GetMetadata (address);
91                 }
92
93                 public MetadataSet GetMetadata (EndpointAddress address)
94                 {
95                         //FIXME: default mode?
96                         return GetMetadataInternal (address, mode);
97                 }
98
99                 public MetadataSet GetMetadata (Uri address, MetadataExchangeClientMode mode)
100                 {
101                         return GetMetadataInternal (new EndpointAddress (address.AbsoluteUri), mode);
102                 }
103
104                 internal MetadataSet GetMetadataInternal (EndpointAddress address, MetadataExchangeClientMode mode)
105                 {
106                         if (binding == null)
107                                 binding = address.Uri.Scheme == Uri.UriSchemeHttps ?
108                                         MetadataExchangeBindings.CreateMexHttpsBinding () :
109                                         MetadataExchangeBindings.CreateMexHttpBinding ();
110
111                         MetadataProxy proxy = new MetadataProxy (binding, address);
112                         proxy.Open ();
113
114                         SMMessage msg = SMMessage.CreateMessage ( 
115                                         MessageVersion.Soap12WSAddressing10, 
116                                         "http://schemas.xmlsoap.org/ws/2004/09/transfer/Get");
117
118                         msg.Headers.ReplyTo = new EndpointAddress (
119                                         "http://www.w3.org/2005/08/addressing/anonymous");
120                         //msg.Headers.From = new EndpointAddress ("http://localhost");
121                         msg.Headers.To = address.Uri;
122                         msg.Headers.MessageId = new UniqueId ();
123
124                         SMMessage ret;
125                         try {
126                                 ret = proxy.Get (msg);
127                         } catch (Exception e) {
128                                 throw new InvalidOperationException (
129                                                 "Metadata contains a reference that cannot be resolved : " + address.Uri.AbsoluteUri, e);
130                         }
131
132                         return MetadataSet.ReadFrom (ret.GetReaderAtBodyContents ());
133                 }
134
135                 // async methods
136
137                 Func<Func<MetadataSet>,MetadataSet> getter;
138
139                 void PrepareGetter ()
140                 {
141                         if (getter == null)
142                                 getter = new Func<Func<MetadataSet>,MetadataSet> (GetMetadata);
143                 }
144
145                 public MetadataSet EndGetMetadata (IAsyncResult result)
146                 {
147                         return getter.EndInvoke (result);
148                 }
149
150                 MetadataSet GetMetadata (Func<MetadataSet> func)
151                 {
152                         return func ();
153                 }
154
155                 public IAsyncResult BeginGetMetadata (AsyncCallback callback, object asyncState)
156                 {
157                         PrepareGetter ();
158                         return getter.BeginInvoke (() => GetMetadata (), callback, asyncState);
159                 }
160
161                 public IAsyncResult BeginGetMetadata (EndpointAddress address, AsyncCallback callback, object asyncState)
162                 {
163                         PrepareGetter ();
164                         return getter.BeginInvoke (() => GetMetadata (address), callback, asyncState);
165                 }
166
167                 public IAsyncResult BeginGetMetadata (Uri address, MetadataExchangeClientMode mode, AsyncCallback callback, object asyncState)
168                 {
169                         PrepareGetter ();
170                         return getter.BeginInvoke (() => GetMetadata (address, mode), callback, asyncState);
171                 }
172         }
173         
174         internal class MetadataProxy : ClientBase<IMetadataExchange>, IMetadataExchange
175         {
176                 public MetadataProxy (SMBinding binding, EndpointAddress address)
177                         : base (binding, address)
178                 {
179                 }
180
181                 public SMMessage Get (SMMessage msg)
182                 {
183                         return Channel.Get (msg);
184                 }
185
186                 public IAsyncResult BeginGet (SMMessage request, AsyncCallback callback , object state)
187                 {
188                         throw new NotImplementedException ();
189                 }
190
191                 public SMMessage EndGet (IAsyncResult result)
192                 {
193                         throw new NotImplementedException ();
194                 }
195         }
196
197 }