1 | # SOAP4R - RPC element definition.
|
---|
2 | # Copyright (C) 2000, 2001, 2003, 2005 NAKAMURA, Hiroshi <[email protected]>.
|
---|
3 |
|
---|
4 | # This program is copyrighted free software by NAKAMURA, Hiroshi. You can
|
---|
5 | # redistribute it and/or modify it under the same terms of Ruby's license;
|
---|
6 | # either the dual license version in 2003, or any later version.
|
---|
7 |
|
---|
8 |
|
---|
9 | require 'soap/baseData'
|
---|
10 |
|
---|
11 |
|
---|
12 | module SOAP
|
---|
13 |
|
---|
14 | # Add method definitions for RPC to common definition in element.rb
|
---|
15 | class SOAPBody < SOAPStruct
|
---|
16 | public
|
---|
17 |
|
---|
18 | def request
|
---|
19 | root_node
|
---|
20 | end
|
---|
21 |
|
---|
22 | def response
|
---|
23 | root = root_node
|
---|
24 | if !@is_fault
|
---|
25 | if root.nil?
|
---|
26 | nil
|
---|
27 | elsif root.is_a?(SOAPBasetype)
|
---|
28 | root
|
---|
29 | else
|
---|
30 | # Initial element is [retval].
|
---|
31 | root[0]
|
---|
32 | end
|
---|
33 | else
|
---|
34 | root
|
---|
35 | end
|
---|
36 | end
|
---|
37 |
|
---|
38 | def outparams
|
---|
39 | root = root_node
|
---|
40 | if !@is_fault and !root.nil? and !root.is_a?(SOAPBasetype)
|
---|
41 | op = root[1..-1]
|
---|
42 | op = nil if op && op.empty?
|
---|
43 | op
|
---|
44 | else
|
---|
45 | nil
|
---|
46 | end
|
---|
47 | end
|
---|
48 |
|
---|
49 | def fault
|
---|
50 | if @is_fault
|
---|
51 | self['fault']
|
---|
52 | else
|
---|
53 | nil
|
---|
54 | end
|
---|
55 | end
|
---|
56 |
|
---|
57 | def fault=(fault)
|
---|
58 | @is_fault = true
|
---|
59 | add_member('fault', fault)
|
---|
60 | end
|
---|
61 | end
|
---|
62 |
|
---|
63 |
|
---|
64 | module RPC
|
---|
65 |
|
---|
66 |
|
---|
67 | class RPCError < Error; end
|
---|
68 | class MethodDefinitionError < RPCError; end
|
---|
69 | class ParameterError < RPCError; end
|
---|
70 |
|
---|
71 | class SOAPMethod < SOAPStruct
|
---|
72 | RETVAL = 'retval'
|
---|
73 | IN = 'in'
|
---|
74 | OUT = 'out'
|
---|
75 | INOUT = 'inout'
|
---|
76 |
|
---|
77 | attr_reader :param_def
|
---|
78 | attr_reader :inparam
|
---|
79 | attr_reader :outparam
|
---|
80 | attr_reader :retval_name
|
---|
81 | attr_reader :retval_class_name
|
---|
82 |
|
---|
83 | def initialize(qname, param_def = nil)
|
---|
84 | super(nil)
|
---|
85 | @elename = qname
|
---|
86 | @encodingstyle = nil
|
---|
87 |
|
---|
88 | @param_def = param_def
|
---|
89 |
|
---|
90 | @signature = []
|
---|
91 | @inparam_names = []
|
---|
92 | @inoutparam_names = []
|
---|
93 | @outparam_names = []
|
---|
94 |
|
---|
95 | @inparam = {}
|
---|
96 | @outparam = {}
|
---|
97 | @retval_name = nil
|
---|
98 | @retval_class_name = nil
|
---|
99 |
|
---|
100 | init_param(@param_def) if @param_def
|
---|
101 | end
|
---|
102 |
|
---|
103 | def have_outparam?
|
---|
104 | @outparam_names.size > 0
|
---|
105 | end
|
---|
106 |
|
---|
107 | def input_params
|
---|
108 | collect_params(IN, INOUT)
|
---|
109 | end
|
---|
110 |
|
---|
111 | def output_params
|
---|
112 | collect_params(OUT, INOUT)
|
---|
113 | end
|
---|
114 |
|
---|
115 | def set_param(params)
|
---|
116 | params.each do |param, data|
|
---|
117 | @inparam[param] = data
|
---|
118 | data.elename.name = param
|
---|
119 | data.parent = self
|
---|
120 | end
|
---|
121 | end
|
---|
122 |
|
---|
123 | def set_outparam(params)
|
---|
124 | params.each do |param, data|
|
---|
125 | @outparam[param] = data
|
---|
126 | data.elename.name = param
|
---|
127 | end
|
---|
128 | end
|
---|
129 |
|
---|
130 | def SOAPMethod.param_count(param_def, *type)
|
---|
131 | count = 0
|
---|
132 | param_def.each do |io_type, name, param_type|
|
---|
133 | if type.include?(io_type)
|
---|
134 | count += 1
|
---|
135 | end
|
---|
136 | end
|
---|
137 | count
|
---|
138 | end
|
---|
139 |
|
---|
140 | def SOAPMethod.derive_rpc_param_def(obj, name, *param)
|
---|
141 | if param.size == 1 and param[0].is_a?(Array)
|
---|
142 | return param[0]
|
---|
143 | end
|
---|
144 | if param.empty?
|
---|
145 | method = obj.method(name)
|
---|
146 | param_names = (1..method.arity.abs).collect { |i| "p#{i}" }
|
---|
147 | else
|
---|
148 | param_names = param
|
---|
149 | end
|
---|
150 | create_rpc_param_def(param_names)
|
---|
151 | end
|
---|
152 |
|
---|
153 | def SOAPMethod.create_rpc_param_def(param_names)
|
---|
154 | param_def = []
|
---|
155 | param_names.each do |param_name|
|
---|
156 | param_def.push([IN, param_name, nil])
|
---|
157 | end
|
---|
158 | param_def.push([RETVAL, 'return', nil])
|
---|
159 | param_def
|
---|
160 | end
|
---|
161 |
|
---|
162 | def SOAPMethod.create_doc_param_def(req_qnames, res_qnames)
|
---|
163 | req_qnames = [req_qnames] if req_qnames.is_a?(XSD::QName)
|
---|
164 | res_qnames = [res_qnames] if res_qnames.is_a?(XSD::QName)
|
---|
165 | param_def = []
|
---|
166 | req_qnames.each do |qname|
|
---|
167 | param_def << [IN, qname.name, [nil, qname.namespace, qname.name]]
|
---|
168 | end
|
---|
169 | res_qnames.each do |qname|
|
---|
170 | param_def << [OUT, qname.name, [nil, qname.namespace, qname.name]]
|
---|
171 | end
|
---|
172 | param_def
|
---|
173 | end
|
---|
174 |
|
---|
175 | private
|
---|
176 |
|
---|
177 | def collect_params(*type)
|
---|
178 | names = []
|
---|
179 | @signature.each do |io_type, name, param_type|
|
---|
180 | names << name if type.include?(io_type)
|
---|
181 | end
|
---|
182 | names
|
---|
183 | end
|
---|
184 |
|
---|
185 | def init_param(param_def)
|
---|
186 | param_def.each do |io_type, name, param_type|
|
---|
187 | case io_type
|
---|
188 | when IN
|
---|
189 | @signature.push([IN, name, param_type])
|
---|
190 | @inparam_names.push(name)
|
---|
191 | when OUT
|
---|
192 | @signature.push([OUT, name, param_type])
|
---|
193 | @outparam_names.push(name)
|
---|
194 | when INOUT
|
---|
195 | @signature.push([INOUT, name, param_type])
|
---|
196 | @inoutparam_names.push(name)
|
---|
197 | when RETVAL
|
---|
198 | if @retval_name
|
---|
199 | raise MethodDefinitionError.new('duplicated retval')
|
---|
200 | end
|
---|
201 | @retval_name = name
|
---|
202 | @retval_class_name = nil
|
---|
203 | if param_type
|
---|
204 | if param_type[0].is_a?(String)
|
---|
205 | @retval_class_name = Mapping.class_from_name(param_type[0])
|
---|
206 | else
|
---|
207 | @retval_class_name = param_type[0]
|
---|
208 | end
|
---|
209 | end
|
---|
210 | else
|
---|
211 | raise MethodDefinitionError.new("unknown type: #{io_type}")
|
---|
212 | end
|
---|
213 | end
|
---|
214 | end
|
---|
215 | end
|
---|
216 |
|
---|
217 |
|
---|
218 | class SOAPMethodRequest < SOAPMethod
|
---|
219 | attr_accessor :soapaction
|
---|
220 |
|
---|
221 | def SOAPMethodRequest.create_request(qname, *params)
|
---|
222 | param_def = []
|
---|
223 | param_value = []
|
---|
224 | i = 0
|
---|
225 | params.each do |param|
|
---|
226 | param_name = "p#{i}"
|
---|
227 | i += 1
|
---|
228 | param_def << [IN, param_name, nil]
|
---|
229 | param_value << [param_name, param]
|
---|
230 | end
|
---|
231 | param_def << [RETVAL, 'return', nil]
|
---|
232 | o = new(qname, param_def)
|
---|
233 | o.set_param(param_value)
|
---|
234 | o
|
---|
235 | end
|
---|
236 |
|
---|
237 | def initialize(qname, param_def = nil, soapaction = nil)
|
---|
238 | check_elename(qname)
|
---|
239 | super(qname, param_def)
|
---|
240 | @soapaction = soapaction
|
---|
241 | end
|
---|
242 |
|
---|
243 | def each
|
---|
244 | input_params.each do |name|
|
---|
245 | unless @inparam[name]
|
---|
246 | raise ParameterError.new("parameter: #{name} was not given")
|
---|
247 | end
|
---|
248 | yield(name, @inparam[name])
|
---|
249 | end
|
---|
250 | end
|
---|
251 |
|
---|
252 | def dup
|
---|
253 | req = self.class.new(@elename.dup, @param_def, @soapaction)
|
---|
254 | req.encodingstyle = @encodingstyle
|
---|
255 | req
|
---|
256 | end
|
---|
257 |
|
---|
258 | def create_method_response(response_name = nil)
|
---|
259 | response_name ||=
|
---|
260 | XSD::QName.new(@elename.namespace, @elename.name + 'Response')
|
---|
261 | SOAPMethodResponse.new(response_name, @param_def)
|
---|
262 | end
|
---|
263 |
|
---|
264 | private
|
---|
265 |
|
---|
266 | def check_elename(qname)
|
---|
267 | # NCName & ruby's method name
|
---|
268 | unless /\A[\w_][\w\d_\-]*\z/ =~ qname.name
|
---|
269 | raise MethodDefinitionError.new("element name '#{qname.name}' not allowed")
|
---|
270 | end
|
---|
271 | end
|
---|
272 | end
|
---|
273 |
|
---|
274 |
|
---|
275 | class SOAPMethodResponse < SOAPMethod
|
---|
276 |
|
---|
277 | def initialize(qname, param_def = nil)
|
---|
278 | super(qname, param_def)
|
---|
279 | @retval = nil
|
---|
280 | end
|
---|
281 |
|
---|
282 | def retval=(retval)
|
---|
283 | @retval = retval
|
---|
284 | @retval.elename = @retval.elename.dup_name(@retval_name || 'return')
|
---|
285 | retval.parent = self
|
---|
286 | retval
|
---|
287 | end
|
---|
288 |
|
---|
289 | def each
|
---|
290 | if @retval_name and [email protected]_a?(SOAPVoid)
|
---|
291 | yield(@retval_name, @retval)
|
---|
292 | end
|
---|
293 |
|
---|
294 | output_params.each do |name|
|
---|
295 | unless @outparam[name]
|
---|
296 | raise ParameterError.new("parameter: #{name} was not given")
|
---|
297 | end
|
---|
298 | yield(name, @outparam[name])
|
---|
299 | end
|
---|
300 | end
|
---|
301 | end
|
---|
302 |
|
---|
303 |
|
---|
304 | # To return(?) void explicitly.
|
---|
305 | # def foo(input_var)
|
---|
306 | # ...
|
---|
307 | # return SOAP::RPC::SOAPVoid.new
|
---|
308 | # end
|
---|
309 | class SOAPVoid < XSD::XSDAnySimpleType
|
---|
310 | include SOAPBasetype
|
---|
311 | extend SOAPModuleUtils
|
---|
312 | Name = XSD::QName.new(Mapping::RubyCustomTypeNamespace, nil)
|
---|
313 |
|
---|
314 | public
|
---|
315 | def initialize()
|
---|
316 | @elename = Name
|
---|
317 | @id = nil
|
---|
318 | @precedents = []
|
---|
319 | @parent = nil
|
---|
320 | end
|
---|
321 | end
|
---|
322 |
|
---|
323 |
|
---|
324 | end
|
---|
325 | end
|
---|