Merge pull request #325 from adbre/iss5464
[mono.git] / mcs / class / System.ServiceModel.Discovery / System.ServiceModel.Discovery / DiscoveryClient.cs
1 //
2 // Author: Atsushi Enomoto <atsushi@ximian.com>
3 //
4 // Copyright (C) 2009,2010 Novell, Inc (http://www.novell.com)
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining
7 // a copy of this software and associated documentation files (the
8 // "Software"), to deal in the Software without restriction, including
9 // without limitation the rights to use, copy, modify, merge, publish,
10 // distribute, sublicense, and/or sell copies of the Software, and to
11 // permit persons to whom the Software is furnished to do so, subject to
12 // the following conditions:
13 // 
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the Software.
16 // 
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 //
25 using System;
26 using System.Collections.Generic;
27 using System.Collections.ObjectModel;
28 using System.ComponentModel;
29 using System.ServiceModel;
30 using System.ServiceModel.Channels;
31 using System.ServiceModel.Description;
32 using System.ServiceModel.Dispatcher;
33
34 namespace System.ServiceModel.Discovery
35 {
36         public sealed class DiscoveryClient : ICommunicationObject, IDisposable
37         {
38                 internal interface IDiscoveryCommon
39                 {
40                         IAsyncResult BeginFind (FindCriteria criteria, AsyncCallback callback, object state);
41                         FindResponse EndFind (IAsyncResult result);
42                         IAsyncResult BeginResolve (ResolveCriteria criteria, AsyncCallback callback, object state);
43                         ResolveResponse EndResolve (IAsyncResult result);
44                 }
45                 
46                 public DiscoveryClient ()
47                         : this (String.Empty)
48                 {
49                 }
50
51                 public DiscoveryClient (DiscoveryEndpoint discoveryEndpoint)
52                 {
53                         if (discoveryEndpoint == null)
54                                 throw new ArgumentNullException ("discoveryEndpoint");
55
56                         // create DiscoveryTargetClientXX for each version:
57                         // Managed -> DiscoveryTargetClientType (request-reply)
58                         // Adhoc   -> DiscoveryProxyClientType (duplex)
59                         if (discoveryEndpoint.DiscoveryMode == ServiceDiscoveryMode.Managed)
60                                 client = Activator.CreateInstance (discoveryEndpoint.DiscoveryVersion.DiscoveryProxyClientType, new object [] {discoveryEndpoint});
61                         else
62                                 client = Activator.CreateInstance (discoveryEndpoint.DiscoveryVersion.DiscoveryTargetClientType, new object [] {discoveryEndpoint});
63                 }
64
65                 public DiscoveryClient (string endpointConfigurationName)
66                 {
67                         throw new NotImplementedException ();
68                 }
69
70                 // FIXME: make it dynamic (dmcs crashes for now)
71                 object client;
72
73                 public ChannelFactory ChannelFactory {
74                         get { return (ChannelFactory) client.GetType ().GetProperty ("ChannelFactory").GetValue (client, null); }
75                 }
76
77                 public ClientCredentials ClientCredentials {
78                         get { return ChannelFactory.Credentials; }
79                 }
80
81                 public ServiceEndpoint Endpoint {
82                         get { return ChannelFactory.Endpoint; }
83                 }
84
85                 public IClientChannel InnerChannel {
86                         get { return (IClientChannel) client.GetType ().GetProperty ("InnerChannel").GetValue (client, null); }
87                 }
88
89                 CommunicationState State {
90                         get { return ((ICommunicationObject) this).State; }
91                 }
92
93                 CommunicationState ICommunicationObject.State {
94                         get { return ((ICommunicationObject) client).State; }
95                 }
96
97                 public event EventHandler<FindCompletedEventArgs> FindCompleted;
98                 public event EventHandler<FindProgressChangedEventArgs> FindProgressChanged;
99                 public event EventHandler<AnnouncementEventArgs> ProxyAvailable;
100                 public event EventHandler<ResolveCompletedEventArgs> ResolveCompleted;
101
102                 event EventHandler ICommunicationObject.Closed {
103                         add { InnerChannel.Closed += value; }
104                         remove { InnerChannel.Closed -= value; }
105                 }
106                 event EventHandler ICommunicationObject.Closing {
107                         add { InnerChannel.Closing += value; }
108                         remove { InnerChannel.Closing -= value; }
109                 }
110                 event EventHandler ICommunicationObject.Faulted {
111                         add { InnerChannel.Faulted += value; }
112                         remove { InnerChannel.Faulted -= value; }
113                 }
114                 event EventHandler ICommunicationObject.Opened {
115                         add { InnerChannel.Opened += value; }
116                         remove { InnerChannel.Opened -= value; }
117                 }
118                 event EventHandler ICommunicationObject.Opening {
119                         add { InnerChannel.Opening += value; }
120                         remove { InnerChannel.Opening -= value; }
121                 }
122
123                 public void Open ()
124                 {
125                         ((ICommunicationObject) this).Open ();
126                 }
127
128                 public void Close ()
129                 {
130                         ((ICommunicationObject) this).Close ();
131                 }
132
133                 bool cancelled;
134
135                 public void CancelAsync (object userState)
136                 {
137                         throw new NotImplementedException ();
138                 }
139
140                 // find
141
142                 public FindResponse Find (FindCriteria criteria)
143                 {
144                         return EndFind (BeginFind (criteria, null, null));
145                 }
146
147                 public void FindAsync (FindCriteria criteria)
148                 {
149                         FindAsync (criteria, null);
150                 }
151
152                 public void FindAsync (FindCriteria criteria, object userState)
153                 {
154                         AsyncCallback cb = delegate (IAsyncResult result) {
155                                 FindResponse ret = null;
156                                 Exception error = null;
157                                 try {
158                                         ret = EndFind (result);
159                                 } catch (Exception ex) {
160                                         error = ex;
161                                 }
162                                 OnFindCompleted (new FindCompletedEventArgs (ret, error, cancelled, result.AsyncState));
163                         };
164                         cancelled = false;
165                         BeginFind (criteria, cb, userState);
166                 }
167
168                 void OnFindCompleted (FindCompletedEventArgs args)
169                 {
170                         if (FindCompleted != null)
171                                 FindCompleted (this, args);
172                 }
173
174                 IAsyncResult BeginFind (FindCriteria criteria, AsyncCallback callback, object state)
175                 {
176                         return ((IDiscoveryCommon) client).BeginFind (criteria, callback, state);
177                 }
178                 
179                 FindResponse EndFind (IAsyncResult result)
180                 {
181                         return ((IDiscoveryCommon) client).EndFind (result);
182                 }
183
184                 // resolve
185
186                 public ResolveResponse Resolve (ResolveCriteria criteria)
187                 {
188                         return EndResolve (BeginResolve (criteria, null, null));
189                 }
190
191                 public void ResolveAsync (ResolveCriteria criteria)
192                 {
193                         ResolveAsync (criteria, null);
194                 }
195
196                 public void ResolveAsync (ResolveCriteria criteria, object userState)
197                 {
198                         AsyncCallback cb = delegate (IAsyncResult result) {
199                                 ResolveResponse ret = null;
200                                 Exception error = null;
201                                 try {
202                                         ret = EndResolve (result);
203                                 } catch (Exception ex) {
204                                         error = ex;
205                                 }
206                                 OnResolveCompleted (new ResolveCompletedEventArgs (ret, error, cancelled, result.AsyncState));
207                         };
208                         cancelled = false;
209                         BeginResolve (criteria, cb, userState);
210                 }
211
212                 void OnResolveCompleted (ResolveCompletedEventArgs args)
213                 {
214                         if (ResolveCompleted != null)
215                                 ResolveCompleted (this, args);
216                 }
217
218                 IAsyncResult BeginResolve (ResolveCriteria criteria, AsyncCallback callback, object state)
219                 {
220                         return ((IDiscoveryCommon) client).BeginResolve (criteria, callback, state);
221                 }
222                 
223                 ResolveResponse EndResolve (IAsyncResult result)
224                 {
225                         return ((IDiscoveryCommon) client).EndResolve (result);
226                 }
227
228                 // explicit interface impl.
229
230                 void ICommunicationObject.Open ()
231                 {
232                         InnerChannel.Open ();
233                 }
234
235                 void ICommunicationObject.Open (TimeSpan timeout)
236                 {
237                         InnerChannel.Open (timeout);
238                 }
239
240                 void ICommunicationObject.Close ()
241                 {
242                         InnerChannel.Close ();
243                 }
244
245                 void ICommunicationObject.Close (TimeSpan timeout)
246                 {
247                         InnerChannel.Close (timeout);
248                 }
249
250                 IAsyncResult ICommunicationObject.BeginOpen (AsyncCallback callback, object state)
251                 {
252                         return InnerChannel.BeginOpen (callback, state);
253                 }
254
255                 IAsyncResult ICommunicationObject.BeginOpen (TimeSpan timeout, AsyncCallback callback, object state)
256                 {
257                         return InnerChannel.BeginOpen (timeout, callback, state);
258                 }
259
260                 IAsyncResult ICommunicationObject.BeginClose (AsyncCallback callback, object state)
261                 {
262                         return InnerChannel.BeginClose (callback, state);
263                 }
264
265                 IAsyncResult ICommunicationObject.BeginClose (TimeSpan timeout, AsyncCallback callback, object state)
266                 {
267                         return InnerChannel.BeginClose (timeout, callback, state);
268                 }
269
270                 void ICommunicationObject.EndOpen (IAsyncResult result)
271                 {
272                         InnerChannel.EndOpen (result);
273                 }
274
275                 void ICommunicationObject.EndClose (IAsyncResult result)
276                 {
277                         InnerChannel.EndClose (result);
278                 }
279
280                 void ICommunicationObject.Abort ()
281                 {
282                         InnerChannel.Abort ();
283                 }
284
285                 void IDisposable.Dispose ()
286                 {
287                         InnerChannel.Dispose ();
288                 }
289         }
290 }