2010-04-02 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Dispatcher / DispatchOperation.cs
1 //
2 // DispatchOperation.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.Collections.Generic;
30 using System.Reflection;
31 using System.ServiceModel;
32 using System.ServiceModel.Channels;
33 using System.ServiceModel.Description;
34 using System.Text;
35
36 namespace System.ServiceModel.Dispatcher
37 {
38         [MonoTODO]
39         public sealed class DispatchOperation
40         {
41                 internal class DispatchOperationCollection :
42                         SynchronizedKeyedCollection<string, DispatchOperation>
43                 {
44                         protected override string GetKeyForItem (DispatchOperation o)
45                         {
46                                 return o.Name;
47                         }
48                 }
49
50                 DispatchRuntime parent;
51                 string name, action, reply_action;
52                 bool serialize_reply = true, deserialize_request = true,
53                         is_oneway, is_terminating,
54                         release_after_call, release_before_call,
55                         tx_auto_complete, tx_required,
56                         auto_dispose_params = true;
57                 ImpersonationOption impersonation;
58                 IDispatchMessageFormatter formatter, actual_formatter;
59                 IOperationInvoker invoker;
60                 SynchronizedCollection<IParameterInspector> inspectors
61                         = new SynchronizedCollection<IParameterInspector> ();
62                 SynchronizedCollection<FaultContractInfo> fault_contract_infos
63                         = new SynchronizedCollection<FaultContractInfo> ();
64                 SynchronizedCollection<ICallContextInitializer> ctx_initializers
65                         = new SynchronizedCollection<ICallContextInitializer> ();
66
67                 public DispatchOperation (DispatchRuntime parent,
68                         string name, string action)
69                 {
70                         if (parent == null)
71                                 throw new ArgumentNullException ("parent");
72                         if (name == null)
73                                 throw new ArgumentNullException ("name");
74                         // action could be null
75
76                         is_oneway = true;
77                         this.parent = parent;
78                         this.name = name;
79                         this.action = action;
80                 }
81
82                 public DispatchOperation (DispatchRuntime parent,
83                         string name, string action, string replyAction)
84                         : this (parent, name, action)
85                 {
86                         // replyAction could be null
87                         is_oneway = false;
88                         reply_action = replyAction;
89                 }
90
91                 public string Action {
92                         get { return action; }
93                 }
94
95                 public SynchronizedCollection<ICallContextInitializer> CallContextInitializers {
96                         get { return ctx_initializers; }
97                 }
98
99                 public bool AutoDisposeParameters {
100                         get { return auto_dispose_params; }
101                         set { auto_dispose_params = value; }
102                 }
103
104                 public bool DeserializeRequest {
105                         get { return deserialize_request; }
106                         set { deserialize_request = value; }
107                 }
108
109                 public SynchronizedCollection<FaultContractInfo> FaultContractInfos {
110                         get { return fault_contract_infos; }
111                 }
112
113                 public IDispatchMessageFormatter Formatter {
114                         get { return formatter; }
115                         set {
116                                 formatter = value;
117                                 actual_formatter = null;
118                         }
119                 }
120
121                 public ImpersonationOption Impersonation {
122                         get { return impersonation; }
123                         set { impersonation = value; }
124                 }
125
126                 public IOperationInvoker Invoker {
127                         get { return invoker; }
128                         set { invoker = value; }
129                 }
130
131                 public bool IsOneWay {
132                         get { return is_oneway; }
133                 }
134
135                 public bool IsTerminating {
136                         get { return is_terminating; }
137                         set { is_terminating = value; }
138                 }
139
140                 public string Name {
141                         get { return name; }
142                 }
143
144                 public SynchronizedCollection<IParameterInspector> ParameterInspectors {
145                         get { return inspectors; }
146                 }
147
148                 public DispatchRuntime Parent {
149                         get { return parent; }
150                 }
151
152                 public bool ReleaseInstanceAfterCall {
153                         get { return release_after_call; }
154                         set { release_after_call = value; }
155                 }
156
157                 public bool ReleaseInstanceBeforeCall {
158                         get { return release_before_call; }
159                         set { release_before_call = value; }
160                 }
161
162                 public string ReplyAction {
163                         get { return reply_action; }
164                 }
165
166                 public bool SerializeReply {
167                         get { return serialize_reply; }
168                         set { serialize_reply = value; }
169                 }
170
171                 public bool TransactionAutoComplete {
172                         get { return tx_auto_complete; }
173                         set { tx_auto_complete = value; }
174                 }
175
176                 public bool TransactionRequired {
177                         get { return tx_required; }
178                         set { tx_required = value; }
179                 }
180
181                 MessageVersion MessageVersion {
182                         get { return Parent.ChannelDispatcher.MessageVersion; }
183                 }
184
185                 OperationDescription Description {
186                         get {
187                                 // FIXME: ContractDescription should be acquired from elsewhere.
188                                 ContractDescription cd = ContractDescription.GetContract (Parent.Type);
189                                 OperationDescription od = cd.Operations.Find (Name);
190                                 if (od == null) {
191                                         if (Name == "*")
192                                                 throw new Exception (String.Format ("INTERNAL ERROR: Contract {0} in namespace {1} does not contain Operations.", Parent.EndpointDispatcher.ContractName, Parent.EndpointDispatcher.ContractNamespace));
193                                         else
194                                                 throw new Exception (String.Format ("INTERNAL ERROR: Operation {0} was not found.", Name));
195                                 }
196                                 return od;
197                         }
198                 }
199
200                 internal IDispatchMessageFormatter GetFormatter ()
201                 {
202                         if (actual_formatter == null) {
203                                 if (Formatter != null)
204                                         actual_formatter = Formatter;
205                                 else
206                                         actual_formatter = new OperationFormatter (Description, false, false); // FIXME: pass correct isRpc, isEncoded
207                         }
208                         return actual_formatter;
209                 }
210         }
211 }