eb03e61fd47948bfcb438b77b4fe81bfc7f6470a
[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 System.ComponentModel;
33 using System.IO;
34 using System.Web.Services;
35
36 namespace System.Web.Services.Protocols {
37         public abstract class SoapMessage {
38
39                 #region Fields
40
41                 string content_type = "text/xml";
42                 string content_encoding;
43                 SoapException exception = null;
44                 SoapHeaderCollection headers;
45                 SoapMessageStage stage;
46                 Stream stream;
47                 object[] inParameters;
48                 object[] outParameters;
49                 
50 #if NET_2_0
51                 SoapProtocolVersion soapVersion;
52 #endif
53
54                 #endregion // Fields
55
56                 #region Constructors
57
58                 internal SoapMessage ()
59                 {
60                         headers = new SoapHeaderCollection ();
61                 }
62
63                 internal SoapMessage (Stream stream, SoapException exception)
64                 {
65                         this.exception = exception;
66                         this.stream = stream;
67                         headers = new SoapHeaderCollection ();
68                 }
69
70                 #endregion
71
72                 #region Properties
73
74                 internal object[] InParameters 
75                 {
76                         get { return inParameters; }
77                         set { inParameters = value; }
78                 }
79
80                 internal object[] OutParameters 
81                 {
82                         get { return outParameters; }
83                         set { outParameters = value; }
84                 }
85
86                 public abstract string Action 
87                 {
88                         get;
89                 }
90
91                 public string ContentType {
92                         get { return content_type; }
93                         set { content_type = value; }
94                 }
95
96                 public SoapException Exception {
97                         get { return exception; }
98 #if NET_2_0
99                         set { exception = value; }
100 #endif
101                 }
102
103                 public SoapHeaderCollection Headers {
104                         get { return headers; }
105                 }
106
107                 public abstract LogicalMethodInfo MethodInfo {
108                         get;
109                 }
110
111                 public abstract bool OneWay {
112                         get;
113                 }
114
115                 public SoapMessageStage Stage {
116                         get { return stage; }
117                 }
118
119                 internal void SetStage (SoapMessageStage stage)
120                 {
121                         this.stage = stage;
122                 }
123                 
124                 public Stream Stream {
125                         get {
126                                 return stream;
127                         }
128                 }
129
130                 public abstract string Url {
131                         get;
132                 }
133                 
134 #if NET_1_1
135                 public string ContentEncoding
136                 {
137                         get { return content_encoding; }
138                         set { content_encoding = value; }
139                 }
140 #else
141                 internal string ContentEncoding
142                 {
143                         get { return content_encoding; }
144                         set { content_encoding = value; }
145                 }
146 #endif
147
148 #if NET_2_0
149                 [System.Runtime.InteropServices.ComVisible(false)]
150                 [DefaultValue (SoapProtocolVersion.Default)]
151                 public virtual SoapProtocolVersion SoapVersion {
152                         get { return soapVersion; }
153                 }
154 #endif
155  
156                 internal Stream InternalStream 
157                 { 
158                         // for getter use public stream property
159                         set {
160                                 stream = value;
161                         }
162                 }
163
164                 #endregion Properties
165
166                 #region Methods
167
168                 protected abstract void EnsureInStage ();
169                 protected abstract void EnsureOutStage ();
170
171                 protected void EnsureStage (SoapMessageStage stage) 
172                 {
173                         if ((((int) stage) & ((int) Stage)) == 0)
174                                 throw new InvalidOperationException ("The current SoapMessageStage is not the asserted stage or stages.");
175                 }
176
177                 public object GetInParameterValue (int index) 
178                 {
179                         return inParameters [index];
180                 }
181
182                 public object GetOutParameterValue (int index) 
183                 {
184                         if (MethodInfo.IsVoid) return outParameters [index];
185                         else return outParameters [index + 1];
186                 }
187
188                 public object GetReturnValue ()
189                 {
190                         if (!MethodInfo.IsVoid && exception == null) return outParameters [0];
191                         else return null;
192                 }
193
194                 internal void SetHeaders (SoapHeaderCollection headers)
195                 {
196                         this.headers = headers;
197                 }
198
199                 internal void SetException (SoapException ex)
200                 {
201                         exception = ex;
202                 }
203
204                 internal void CollectHeaders (object target, HeaderInfo[] headers, SoapHeaderDirection direction)
205                 {
206                         Headers.Clear ();
207                         foreach (HeaderInfo hi in headers) 
208                         {
209                                 if ((hi.Direction & direction) != 0 && !hi.IsUnknownHeader) 
210                                 {
211                                         SoapHeader headerVal = hi.GetHeaderValue (target) as SoapHeader;
212                                         if (headerVal != null)
213                                                 Headers.Add (headerVal);
214                                 }
215                         }
216                 }
217
218                 internal void UpdateHeaderValues (object target, HeaderInfo[] headersInfo)
219                 {
220                         foreach (SoapHeader header in Headers)
221                         {
222                                 HeaderInfo hinfo = FindHeader (headersInfo, header.GetType ());
223                                 if (hinfo != null) {
224                                         hinfo.SetHeaderValue (target, header);
225                                         header.DidUnderstand = !hinfo.IsUnknownHeader;
226                                 }
227                         }
228                 }
229
230                 HeaderInfo FindHeader (HeaderInfo[] headersInfo, Type headerType)
231                 {
232                         HeaderInfo unknownHeaderInfo = null;
233                 
234                         foreach (HeaderInfo headerInfo in headersInfo) {
235                                 if (headerInfo.HeaderType == headerType)
236                                         return headerInfo;
237                                 else if (headerInfo.IsUnknownHeader) 
238                                         unknownHeaderInfo = headerInfo;
239                         }
240                         return unknownHeaderInfo;
241                 }
242
243                 #endregion // Methods
244         }
245 }