2003-07-09: Jean-Marc Andr�� <jean-marc.andre@polymtl.cs>
[mono.git] / mcs / class / System.Runtime.Remoting / System.Runtime.Remoting.Channels / SoapClientFormatterSink.cs
1 //\r
2 // System.Runtime.Remoting.Channels.SoapClientFormatterSink.cs\r
3 //\r
4 // Authors:     Rodrigo Moya (rodrigo@ximian.com)\r
5 //              Jean-Marc André (jean-marc.andre@polymtl.ca)\r
6 //\r
7 // 2002 (C) Copyright, Ximian, Inc.\r
8 //\r
9 \r
10 using System.Collections;\r
11 using System.IO;\r
12 using System.Reflection;\r
13 using System.Runtime.Remoting.Messaging;\r
14 using System.Runtime.Serialization;\r
15 using System.Runtime.Serialization.Formatters;\r
16 using System.Runtime.Serialization.Formatters.Soap;\r
17 \r
18 namespace System.Runtime.Remoting.Channels\r
19 {\r
20         public class SoapClientFormatterSink : IClientFormatterSink,\r
21                 IMessageSink, IClientChannelSink, IChannelSinkBase\r
22         {\r
23                 private IClientChannelSink _nextChannelSink;\r
24                 private SoapFormatter _serializationFormatter;\r
25                 private SoapFormatter _deserializationFormatter;\r
26                 \r
27                 public SoapClientFormatterSink (IClientChannelSink sink)\r
28                 {\r
29                         _nextChannelSink = sink;\r
30                         RemotingSurrogateSelector surrogateSelector = new RemotingSurrogateSelector();\r
31                         StreamingContext context = new StreamingContext(StreamingContextStates.Remoting);\r
32                         _serializationFormatter = new SoapFormatter(surrogateSelector, context);\r
33                         _deserializationFormatter = new SoapFormatter(null, context);\r
34                 }\r
35                 \r
36                 // IClientChannelSink\r
37                 public IClientChannelSink NextChannelSink\r
38                 {\r
39                         get {\r
40                                 return _nextChannelSink;\r
41                         }\r
42                 }\r
43                 \r
44                 // IMessageSink\r
45                 public IMessageSink NextSink\r
46                 {\r
47                         get {\r
48                                 return null ;\r
49                         }\r
50                 }\r
51                 \r
52                 // IChannelSinkBase\r
53                 public IDictionary Properties\r
54                 {\r
55                         get {\r
56                                 return null;\r
57                         }\r
58                 }\r
59 \r
60                 public IMessageCtrl AsyncProcessMessage (IMessage msg,\r
61                                                          IMessageSink replySink)\r
62                 {\r
63                         Stream requestStream;\r
64                         ITransportHeaders requestHeaders;\r
65                         SoapMessageFormatter soapMsgFormatter;\r
66                         \r
67                         SerializeMessage(msg, out requestStream, out requestHeaders, out soapMsgFormatter);\r
68 \r
69                         ClientChannelSinkStack stack = new ClientChannelSinkStack(replySink);\r
70                         stack.Push(this, soapMsgFormatter);\r
71 \r
72                         _nextChannelSink.AsyncProcessRequest(stack, msg, requestHeaders, requestStream);\r
73 \r
74                         return null;\r
75                 }\r
76 \r
77                 public void AsyncProcessRequest (IClientChannelSinkStack sinkStack,\r
78                                                  IMessage msg,\r
79                                                  ITransportHeaders headers,\r
80                                                  Stream stream)\r
81                 {\r
82                         // this method should never be called\r
83                         throw new NotSupportedException ();\r
84                 }\r
85 \r
86                 public void AsyncProcessResponse (IClientResponseChannelSinkStack sinkStack,\r
87                                                   object state,\r
88                                                   ITransportHeaders headers,\r
89                                                   Stream stream)\r
90                 {\r
91                         SoapMessageFormatter soapMsgFormatter = (SoapMessageFormatter)state;\r
92 \r
93                         IMessage replyMessage = (IMessage) DeserializeMessage(stream, headers, (IMethodCallMessage)state, soapMsgFormatter);\r
94 \r
95                         sinkStack.DispatchReplyMessage(replyMessage);\r
96                         \r
97                 }\r
98 \r
99                 public Stream GetRequestStream (IMessage msg,\r
100                                                 ITransportHeaders headers)\r
101                 {\r
102                         // First sink in the chain so this method should never\r
103                         // be called\r
104                         throw new NotSupportedException ();\r
105                 }\r
106 \r
107                 public void ProcessMessage (IMessage msg,\r
108                                             ITransportHeaders requestHeaders,\r
109                                             Stream requestStream,\r
110                                             out ITransportHeaders responseHeaders,\r
111                                             out Stream responseStream)\r
112                 {\r
113                         // First sink in the chain so this method should never\r
114                         // be called\r
115                         throw new NotSupportedException ();\r
116                         \r
117                 }\r
118 \r
119 //              ////[MonoTODO]\r
120                 public IMessage SyncProcessMessage (IMessage msg)\r
121                 {\r
122                         Stream requestStream, responseStream;\r
123                         ITransportHeaders requestHeaders, responseHeaders;\r
124                         SoapMessageFormatter soapMsgFormatter;\r
125                         \r
126                         SerializeMessage(msg, out requestStream, out requestHeaders, out soapMsgFormatter);\r
127                         _nextChannelSink.ProcessMessage(msg, requestHeaders, requestStream, out responseHeaders, out responseStream);\r
128                         \r
129                         return DeserializeMessage(responseStream, responseHeaders, (IMethodCallMessage)msg, soapMsgFormatter);\r
130                 }\r
131                 \r
132                 \r
133                 private void SerializeMessage(IMessage msg, out Stream requestStream, out ITransportHeaders requestHeaders, out SoapMessageFormatter soapMsgFormatter) {\r
134                         SoapMessage soapMsg;\r
135                         soapMsgFormatter = new SoapMessageFormatter();\r
136                         soapMsg = soapMsgFormatter.BuildSoapMessageFromMethodCall((IMethodCallMessage) msg, out requestHeaders);\r
137                         \r
138                         // Get the stream where the message will be serialized\r
139                         requestStream = _nextChannelSink.GetRequestStream(msg, requestHeaders);\r
140                         \r
141                         if(requestStream == null) requestStream = new MemoryStream();\r
142                         \r
143                         // Serialize the message into the stream\r
144                         _serializationFormatter.Serialize(requestStream, soapMsg, null);\r
145                         \r
146                         if(requestStream is MemoryStream){\r
147                                 requestStream.Position = 0;\r
148                         }\r
149 \r
150                         \r
151                 }\r
152                 \r
153                 \r
154                 private IMessage DeserializeMessage(Stream responseStream, ITransportHeaders responseHeaders,IMethodCallMessage mcm, SoapMessageFormatter soapMsgFormatter) {\r
155                         SoapMessage rtnMessage = new SoapMessage();\r
156                         _deserializationFormatter.TopObject = rtnMessage;\r
157                         object objReturn = _deserializationFormatter.Deserialize(responseStream);\r
158                         \r
159                         return soapMsgFormatter.FormatResponse((ISoapMessage) objReturn, mcm);\r
160                         \r
161                         \r
162                 }\r
163         }\r
164 }\r