BindingFlags.Public needed here as Exception.HResult is now public in .NET 4.5. This...
[mono.git] / mcs / class / System.Web.Services / System.Web.Services.Protocols / SoapMessage.cs
1 // 
2 // System.Web.Services.Protocols.SoapMessage.cs
3 //
4 // Author:
5 //   Tim Coleman (tim@timcoleman.com)
6 //   Lluis Sanchez Gual (lluis@ximian.com)
7 //
8 // Copyright (C) Tim Coleman, 2002
9 //
10
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using HeaderInfo = System.Web.Services.Protocols.SoapHeaderMapping;
33
34 using System.ComponentModel;
35 using System.IO;
36 using System.Web.Services;
37
38 namespace System.Web.Services.Protocols {
39         public abstract class SoapMessage {
40
41                 #region Fields
42
43                 string content_type = "text/xml";
44                 string content_encoding;
45                 SoapException exception = null;
46                 SoapHeaderCollection headers;
47                 SoapMessageStage stage;
48                 Stream stream;
49                 object[] inParameters;
50                 object[] outParameters;
51                 
52 #if NET_2_0
53                 SoapProtocolVersion soapVersion;
54 #endif
55
56                 #endregion // Fields
57
58                 #region Constructors
59
60                 internal SoapMessage ()
61                 {
62                         headers = new SoapHeaderCollection ();
63                 }
64
65                 internal SoapMessage (Stream stream, SoapException exception)
66                 {
67                         this.exception = exception;
68                         this.stream = stream;
69                         headers = new SoapHeaderCollection ();
70                 }
71
72                 #endregion
73
74                 #region Properties
75
76                 internal object[] InParameters 
77                 {
78                         get { return inParameters; }
79                         set { inParameters = value; }
80                 }
81
82                 internal object[] OutParameters 
83                 {
84                         get { return outParameters; }
85                         set { outParameters = value; }
86                 }
87
88                 public abstract string Action 
89                 {
90                         get;
91                 }
92
93                 public string ContentType {
94                         get { return content_type; }
95                         set { content_type = value; }
96                 }
97
98                 public SoapException Exception {
99                         get { return exception; }
100 #if NET_2_0
101                         set { exception = value; }
102 #endif
103                 }
104
105                 public SoapHeaderCollection Headers {
106                         get { return headers; }
107                 }
108
109                 public abstract LogicalMethodInfo MethodInfo {
110                         get;
111                 }
112
113                 public abstract bool OneWay {
114                         get;
115                 }
116
117                 public SoapMessageStage Stage {
118                         get { return stage; }
119                 }
120
121                 internal void SetStage (SoapMessageStage stage)
122                 {
123                         this.stage = stage;
124                 }
125                 
126                 public Stream Stream {
127                         get {
128                                 return stream;
129                         }
130                 }
131
132                 public abstract string Url {
133                         get;
134                 }
135                 
136 #if NET_1_1
137                 public string ContentEncoding
138                 {
139                         get { return content_encoding; }
140                         set { content_encoding = value; }
141                 }
142 #else
143                 internal string ContentEncoding
144                 {
145                         get { return content_encoding; }
146                         set { content_encoding = value; }
147                 }
148 #endif
149
150                 internal bool IsSoap12 {
151                         get {
152 #if NET_2_0
153                                 return SoapVersion == SoapProtocolVersion.Soap12;
154 #else
155                                 return false;
156 #endif
157                         }
158                 }
159
160 #if NET_2_0
161                 [System.Runtime.InteropServices.ComVisible(false)]
162                 [DefaultValue (SoapProtocolVersion.Default)]
163                 public virtual SoapProtocolVersion SoapVersion {
164                         get { return soapVersion; }
165                 }
166 #endif
167  
168                 internal Stream InternalStream 
169                 { 
170                         // for getter use public stream property
171                         set {
172                                 stream = value;
173                         }
174                 }
175
176                 #endregion Properties
177
178                 #region Methods
179
180                 protected abstract void EnsureInStage ();
181                 protected abstract void EnsureOutStage ();
182
183                 protected void EnsureStage (SoapMessageStage stage) 
184                 {
185                         if ((((int) stage) & ((int) Stage)) == 0)
186                                 throw new InvalidOperationException ("The current SoapMessageStage is not the asserted stage or stages.");
187                 }
188
189                 public object GetInParameterValue (int index) 
190                 {
191                         return inParameters [index];
192                 }
193
194                 public object GetOutParameterValue (int index) 
195                 {
196                         if (MethodInfo.IsVoid) return outParameters [index];
197                         else return outParameters [index + 1];
198                 }
199
200                 public object GetReturnValue ()
201                 {
202                         if (!MethodInfo.IsVoid && exception == null) return outParameters [0];
203                         else return null;
204                 }
205
206                 internal void SetHeaders (SoapHeaderCollection headers)
207                 {
208                         this.headers = headers;
209                 }
210
211                 internal void SetException (SoapException ex)
212                 {
213                         exception = ex;
214                 }
215
216                 internal void CollectHeaders (object target, HeaderInfo[] headers, SoapHeaderDirection direction)
217                 {
218                         Headers.Clear ();
219                         foreach (HeaderInfo hi in headers) 
220                         {
221                                 if ((hi.Direction & direction) != 0 && !hi.Custom) 
222                                 {
223                                         SoapHeader headerVal = hi.GetHeaderValue (target) as SoapHeader;
224                                         if (headerVal != null)
225                                                 Headers.Add (headerVal);
226                                 }
227                         }
228                 }
229
230                 internal void UpdateHeaderValues (object target, HeaderInfo[] headersInfo)
231                 {
232                         foreach (SoapHeader header in Headers)
233                         {
234                                 HeaderInfo hinfo = FindHeader (headersInfo, header.GetType ());
235                                 if (hinfo != null) {
236                                         hinfo.SetHeaderValue (target, header);
237                                         header.DidUnderstand = !hinfo.Custom;
238                                 }
239                         }
240                 }
241
242                 HeaderInfo FindHeader (HeaderInfo[] headersInfo, Type headerType)
243                 {
244                         HeaderInfo unknownHeaderInfo = null;
245                 
246                         foreach (HeaderInfo headerInfo in headersInfo) {
247                                 if (headerInfo.HeaderType == headerType)
248                                         return headerInfo;
249                                 else if (headerInfo.Custom) 
250                                         unknownHeaderInfo = headerInfo;
251                         }
252                         return unknownHeaderInfo;
253                 }
254
255                 #endregion // Methods
256         }
257 }