move to from olive to mcs
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / BindingContext.cs
1 //
2 // BindingContext.cs
3 //
4 // Author:
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 using System;
29 using System.Collections.Generic;
30 using System.ServiceModel;
31 using System.ServiceModel.Description;
32 using System.ServiceModel.Security;
33
34 namespace System.ServiceModel.Channels
35 {
36         public class BindingContext
37         {
38                 static BindingElementCollection empty_collection =
39                         new BindingElementCollection ();
40
41                 CustomBinding binding;
42                 BindingParameterCollection parameters;
43                 BindingElementCollection elements = empty_collection;
44                 BindingElementCollection remaining_elements;
45                 Uri listen_uri_base;
46                 string listen_uri_relative;
47                 ListenUriMode listen_uri_mode;
48
49                 public BindingContext (CustomBinding binding,
50                         BindingParameterCollection parameters)
51                 {
52                         if (binding == null)
53                                 throw new ArgumentNullException ("binding");
54                         if (parameters == null)
55                                 throw new ArgumentNullException ("parameters");
56
57                         this.binding = binding;
58                         this.parameters = parameters;
59                 }
60
61                 public BindingContext (CustomBinding binding,
62                         BindingParameterCollection parameters,
63                         Uri listenUriBaseAddress,
64                         string listenUriRelativeAddress,
65                         ListenUriMode listenUriMode)
66                         : this (binding, parameters)
67                 {
68                         listen_uri_base = listenUriBaseAddress;
69                         listen_uri_relative = listenUriRelativeAddress;
70                         listen_uri_mode = listenUriMode;
71                 }
72
73                 // copy .ctor().
74                 private BindingContext (BindingContext other)
75                 {
76                         binding = other.binding;
77                         parameters = other.parameters;
78                         elements = other.elements == empty_collection ?
79                                 empty_collection : other.elements.Clone ();
80                 }
81
82                 public CustomBinding Binding {
83                         get { return binding; }
84                 }
85
86                 public BindingParameterCollection BindingParameters {
87                         get { return parameters; }
88                 }
89
90                 public Uri ListenUriBaseAddress {
91                         get { return listen_uri_base; }
92                         set { listen_uri_base = value; }
93                 }
94
95                 public string ListenUriRelativeAddress {
96                         get { return listen_uri_relative; }
97                         set { listen_uri_relative = value; }
98                 }
99
100                 public ListenUriMode ListenUriMode {
101                         get { return listen_uri_mode; }
102                         set { listen_uri_mode = value; }
103                 }
104
105                 public BindingElementCollection RemainingBindingElements {
106                         get {
107                                 if (remaining_elements == null)
108                                         remaining_elements = new BindingElementCollection ();
109                                 return remaining_elements;
110                         }
111                 }
112
113                 internal BindingElement DequeueBindingElement ()
114                 {
115                         return DequeueBindingElement (true);
116                 }
117
118                 BindingElement DequeueBindingElement (bool raiseError)
119                 {
120                         if (elements.Count == 0) {
121                                 if (raiseError)
122                                         throw new InvalidOperationException ("There is no more available binding element.");
123                                 else
124                                         return null;
125                         }
126                         BindingElement el = elements [0];
127                         elements.RemoveAt (0);
128                         return el;
129                 }
130
131                 private bool PrepareElements ()
132                 {
133                         if (elements != empty_collection)
134                                 return false;
135                         elements = binding.CreateBindingElements ();
136                         return true;
137                 }
138
139                 public IChannelFactory<TChannel>
140                         BuildInnerChannelFactory<TChannel> ()
141                 {
142                         bool restore = PrepareElements ();
143                         try {
144                                 return DequeueBindingElement ().BuildChannelFactory<TChannel> (this);
145                         } finally {
146                                 if (restore)
147                                         elements = empty_collection;
148                         }
149                 }
150
151                 public IChannelListener<TChannel>
152                         BuildInnerChannelListener<TChannel> ()
153                         where TChannel : class, IChannel
154                 {
155                         bool restore = PrepareElements ();
156                         try {
157                                 return DequeueBindingElement ().BuildChannelListener<TChannel> (this);
158                         } finally {
159                                 if (restore)
160                                         elements = empty_collection;
161                         }
162                 }
163
164                 public bool CanBuildInnerChannelFactory<TChannel> ()
165                 {
166                         bool restore = PrepareElements ();
167                         try {
168                                 return elements.Count > 0 &&
169                                         DequeueBindingElement ().CanBuildChannelFactory<TChannel> (this);
170                         } finally {
171                                 if (restore)
172                                         elements = empty_collection;
173                         }
174                 }
175
176                 public bool CanBuildInnerChannelListener<TChannel> ()
177                         where TChannel : class, IChannel
178                 {
179                         bool restore = PrepareElements ();
180                         try {
181                                 return elements.Count > 0 &&
182                                         DequeueBindingElement ().CanBuildChannelListener<TChannel> (this);
183                         } finally {
184                                 if (restore)
185                                         elements = empty_collection;
186                         }
187                 }
188
189                 public T GetInnerProperty<T> () where T : class
190                 {
191                         bool restore = PrepareElements ();
192                         try {
193                                 BindingElement e = DequeueBindingElement (false);
194                                 return e == null ? default (T) : e.GetProperty<T> (this);
195                         } finally {
196                                 if (restore)
197                                         elements = empty_collection;
198                         }
199                 }
200
201                 public BindingContext Clone ()
202                 {
203                         return new BindingContext (this);
204                 }
205         }
206 }