move to from olive to mcs
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / CommunicationObject.cs
1 //
2 // CommunicationObject.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2005 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 using System;
29 using System.ServiceModel;
30 using System.Threading;
31
32 namespace System.ServiceModel.Channels
33 {
34         public abstract class CommunicationObject : ICommunicationObject
35         {
36                 object mutex;
37                 CommunicationState state = CommunicationState.Created;
38                 TimeSpan open_timeout, close_timeout;
39                 bool aborted;
40
41                 protected CommunicationObject ()
42                         : this (new object ())
43                 {
44                 }
45
46                 protected CommunicationObject (object mutex)
47                 {
48                         this.mutex = mutex;
49                 }
50
51                 #region Events
52
53                 public event EventHandler Closed;
54
55                 public event EventHandler Closing;
56
57                 public event EventHandler Faulted;
58
59                 public event EventHandler Opened;
60
61                 public event EventHandler Opening;
62
63                 #endregion
64
65                 #region Properties
66
67                 public CommunicationState State {
68                         get { return state; }
69                 }
70
71                 protected bool IsDisposed {
72                         get { return state == CommunicationState.Closed; }
73                 }
74
75                 protected object ThisLock {
76                         get { return mutex; }
77                 }
78
79                 protected internal abstract TimeSpan DefaultCloseTimeout { get; }
80
81                 protected internal abstract TimeSpan DefaultOpenTimeout { get; }
82
83                 #endregion
84
85                 #region Methods
86
87                 [MonoTODO]
88                 public void Abort ()
89                 {
90                         OnAbort ();
91                 }
92
93                 [MonoTODO]
94                 protected void Fault ()
95                 {
96                         state = CommunicationState.Faulted;
97                         OnFaulted ();
98                 }
99
100                 public IAsyncResult BeginClose (AsyncCallback callback,
101                         object state)
102                 {
103                         return BeginClose (close_timeout, callback, state);
104                 }
105
106                 public IAsyncResult BeginClose (TimeSpan timeout,
107                         AsyncCallback callback, object state)
108                 {
109                         ProcessClosing ();
110                         return OnBeginClose (timeout, callback, state);
111                 }
112
113                 public IAsyncResult BeginOpen (AsyncCallback callback,
114                         object state)
115                 {
116                         return BeginOpen (open_timeout, callback, state);
117                 }
118
119                 public IAsyncResult BeginOpen (TimeSpan timeout,
120                         AsyncCallback callback, object state)
121                 {
122                         ProcessOpening ();
123                         return OnBeginOpen (timeout, callback, state);
124                 }
125
126                 public void Close ()
127                 {
128                         Close (close_timeout);
129                 }
130
131                 public void Close (TimeSpan timeout)
132                 {
133                         ProcessClosing ();
134                         OnClose (timeout);
135                         ProcessClosed ();
136                 }
137
138                 public void EndClose (IAsyncResult result)
139                 {
140                         OnEndClose (result);
141                         ProcessClosed ();
142                 }
143
144                 public void EndOpen (IAsyncResult result)
145                 {
146                         OnEndOpen (result);
147                         ProcessOpened ();
148                 }
149
150                 public void Open ()
151                 {
152                         Open (open_timeout);
153                 }
154
155                 public void Open (TimeSpan timeout)
156                 {
157                         ProcessOpening ();
158                         OnOpen (timeout);
159                         ProcessOpened ();
160                 }
161
162                 protected abstract void OnAbort ();
163
164                 protected abstract IAsyncResult OnBeginClose (TimeSpan timeout,
165                         AsyncCallback callback, object state);
166
167                 protected abstract IAsyncResult OnBeginOpen (TimeSpan timeout,
168                         AsyncCallback callback, object state);
169
170                 protected abstract void OnClose (TimeSpan timeout);
171
172                 void ProcessClosing ()
173                 {
174                         if (State == CommunicationState.Faulted)
175                                 throw new CommunicationObjectFaultedException ();
176                         state = CommunicationState.Closing;
177                         OnClosing ();
178                 }
179
180                 protected virtual void OnClosing ()
181                 {
182                         // This means, if this method is overriden, then
183                         // Opening event is surpressed.
184                         if (Closing != null)
185                                 Closing (this, new EventArgs ());
186                 }
187
188                 void ProcessClosed ()
189                 {
190                         state = CommunicationState.Closed;
191                         OnClosed ();
192                 }
193
194                 protected virtual void OnClosed ()
195                 {
196                         // This means, if this method is overriden, then
197                         // Closed event is surpressed.
198                         if (Closed != null)
199                                 Closed (this, new EventArgs ());
200                 }
201
202                 protected abstract void OnEndClose (IAsyncResult result);
203
204                 protected abstract void OnEndOpen (IAsyncResult result);
205
206                 [MonoTODO]
207                 protected virtual void OnFaulted ()
208                 {
209                         // This means, if this method is overriden, then
210                         // Opened event is surpressed.
211                         if (Faulted != null)
212                                 Faulted (this, new EventArgs ());
213                 }
214
215                 protected abstract void OnOpen (TimeSpan timeout);
216
217                 void ProcessOpened ()
218                 {
219                         state = CommunicationState.Opened;
220                         OnOpened ();
221                 }
222
223                 protected virtual void OnOpened ()
224                 {
225                         // This means, if this method is overriden, then
226                         // Opened event is surpressed.
227                         if (Opened != null)
228                                 Opened (this, new EventArgs ());
229                 }
230
231                 void ProcessOpening ()
232                 {
233                         ThrowIfDisposedOrImmutable ();
234                         state = CommunicationState.Opening;
235                         OnOpening ();
236                 }
237
238                 protected virtual void OnOpening ()
239                 {
240                         // This means, if this method is overriden, then
241                         // Opening event is surpressed.
242                         if (Opening != null)
243                                 Opening (this, new EventArgs ());
244                 }
245
246                 protected void ThrowIfDisposed ()
247                 {
248                         if (IsDisposed)
249                                 throw new ObjectDisposedException (String.Format ("This communication object {0} is already disposed.", GetCommunicationObjectType ()));
250                 }
251
252                 protected void ThrowIfDisposedOrNotOpen ()
253                 {
254                         ThrowIfDisposed ();
255                         if (State == CommunicationState.Faulted)
256                                 throw new CommunicationObjectFaultedException ();
257                         if (State != CommunicationState.Opened)
258                                 throw new InvalidOperationException (String.Format ("The communication object {0} must be at opened state.", GetCommunicationObjectType ()));
259                 }
260
261                 protected void ThrowIfDisposedOrImmutable ()
262                 {
263                         ThrowIfDisposed ();
264                         // hmm, according to msdn, Closing is OK here.
265                         switch (State) {
266                         case CommunicationState.Faulted:
267                                 throw new CommunicationObjectFaultedException ();
268                         case CommunicationState.Opening:
269                         case CommunicationState.Opened:
270                                 throw new InvalidOperationException (String.Format ("The communication object {0} is not at created state.", GetType ()));
271                         }
272                 }
273
274                 protected virtual Type GetCommunicationObjectType ()
275                 {
276                         return GetType ();
277                 }
278
279                 #endregion
280
281
282                 class SimpleAsyncResult : IAsyncResult
283                 {
284                         CommunicationState comm_state;
285                         object async_state;
286
287                         public SimpleAsyncResult (
288                                 CommunicationState communicationState,
289                                 TimeSpan timeout, AsyncCallback callback,
290                                 object asyncState)
291                         {
292                                 comm_state = communicationState;
293                                 async_state = asyncState;
294                         }
295
296                         public object AsyncState {
297                                 get { return async_state; }
298                         }
299
300                         // FIXME: implement
301                         public WaitHandle AsyncWaitHandle {
302                                 get { throw new NotImplementedException (); }
303                         }
304
305                         // FIXME: implement
306                         public bool CompletedSynchronously {
307                                 get { throw new NotImplementedException (); }
308                         }
309
310                         // FIXME: implement
311                         public bool IsCompleted {
312                                 get { throw new NotImplementedException (); }
313                         }
314                 }
315         }
316 }