File: element.rb

package info (click to toggle)
ruby-soap4r 2.0.5-9
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,032 kB
  • sloc: ruby: 52,729; xml: 266; sh: 42; javascript: 20; makefile: 13; perl: 10
file content (374 lines) | stat: -rw-r--r-- 7,965 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
# SOAP4R - RPC element definition.
# Copyright (C) 2000-2007  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/baseData'
require 'soap/rpc/methodDef'


module SOAP

# Add method definitions for RPC to common definition in element.rb
class SOAPBody < SOAPStruct
  public

  def request
    root_node
  end

  def response
    root = root_node
    if !@is_fault
      if root.nil?
        nil
      elsif root.is_a?(SOAPBasetype)
        root
      else
        # Initial element is [retval].
        root[0]
      end
    else
      root
    end
  end

  def outparams
    root = root_node
    if !@is_fault and !root.nil? and !root.is_a?(SOAPBasetype)
      op = root[1..-1]
      op = nil if op && op.empty?
      op
    else
      nil
    end
  end

  def fault
    if @is_fault
      self['fault']
    else
      nil
    end
  end

  def fault=(fault)
    @is_fault = true
    add('fault', fault)
  end
end


module RPC


class RPCError < Error; end
class MethodDefinitionError < RPCError; end
class ParameterError < RPCError; end

class SOAPMethod < SOAPStruct
  RETVAL = :retval
  IN = :in
  OUT = :out
  INOUT = :inout

  attr_reader :param_def
  attr_reader :inparam
  attr_reader :outparam
  attr_reader :retval_name
  attr_reader :retval_class_name

  def initialize(qname, param_def = nil)
    super(nil)
    @elename = qname
    @encodingstyle = nil

    @param_def = param_def

    @signature = []
    @inparam_names = []
    @inoutparam_names = []
    @outparam_names = []

    @inparam = {}
    @outparam = {}
    @retval_name = nil
    @retval_class_name = nil

    init_params(@param_def) if @param_def
  end

  def have_member
    true
  end

  def have_outparam?
    @outparam_names.size > 0
  end

  def input_params
    collect_params(IN, INOUT)
  end

  def output_params
    collect_params(OUT, INOUT)
  end

  def input_param_types
    collect_param_types(IN, INOUT)
  end

  def output_param_types
    collect_param_types(OUT, INOUT)
  end

  def set_param(params)
    params.each do |param, data|
      @inparam[param] = data
      data.elename = XSD::QName.new(data.elename.namespace, param)
      data.parent = self
    end
  end

  def set_outparam(params)
    params.each do |param, data|
      @outparam[param] = data
      data.elename = XSD::QName.new(data.elename.namespace, param)
    end
  end

  def get_paramtypes(names)
    types = []
    @signature.each do |io_type, name, type_qname|
      if type_qname && idx = names.index(name)
        types[idx] = type_qname
      end
    end
    types
  end

  def SOAPMethod.param_count(param_def, *type)
    count = 0
    param_def.each do |param|
      param = MethodDef.to_param(param)
      if type.include?(param.io_type.to_sym)
        count += 1
      end
    end
    count
  end

  def SOAPMethod.derive_rpc_param_def(obj, name, *param)
    if param.size == 1 and param[0].is_a?(Array)
      return param[0]
    end
    if param.empty?
      method = obj.method(name)
      param_names = (1..method.arity.abs).collect { |i| "p#{i}" }
    else
      param_names = param
    end
    create_rpc_param_def(param_names)
  end

  def SOAPMethod.create_rpc_param_def(param_names)
    param_def = []
    param_names.each do |param_name|
      param_def.push([IN, param_name, nil])
    end
    param_def.push([RETVAL, 'return', nil])
    param_def
  end

  def SOAPMethod.create_doc_param_def(req_qnames, res_qnames)
    req_qnames = [req_qnames] if req_qnames.is_a?(XSD::QName)
    res_qnames = [res_qnames] if res_qnames.is_a?(XSD::QName)
    param_def = []
    # req_qnames and res_qnames can be nil
    if req_qnames
      req_qnames.each do |qname|
        param_def << [IN, qname.name, [nil, qname.namespace, qname.name]]
      end
    end
    if res_qnames
      res_qnames.each do |qname|
        param_def << [OUT, qname.name, [nil, qname.namespace, qname.name]]
      end
    end
    param_def
  end

private

  def collect_param_types(*type)
    names = []
    @signature.each do |io_type, name, type_qname|
      names << type_qname if type.include?(io_type)
    end
    names
  end

  def collect_params(*type)
    names = []
    @signature.each do |io_type, name, type_qname|
      names << name if type.include?(io_type)
    end
    names
  end

  def init_params(param_def)
    param_def.each do |param|
      param = MethodDef.to_param(param)
      init_param(param)
    end
  end

  def init_param(param)
    mapped_class = SOAPMethod.parse_mapped_class(param.mapped_class)
    qname = param.qname
    if qname.nil? and mapped_class
      qname = TypeMap.key(mapped_class)
    end
    case param.io_type
    when IN
      @signature.push([IN, param.name, qname])
      @inparam_names.push(param.name)
    when OUT
      @signature.push([OUT, param.name, qname])
      @outparam_names.push(param.name)
    when INOUT
      @signature.push([INOUT, param.name, qname])
      @inoutparam_names.push(param.name)
    when RETVAL
      if @retval_name
        raise MethodDefinitionError.new('duplicated retval')
      end
      @retval_name = param.name
      @retval_class_name = mapped_class
    else
      raise MethodDefinitionError.new("unknown type: #{param.io_type}")
    end
  end

  def self.parse_mapped_class(mapped_class)
    # the first element of typedef in param_def can be a String like
    # "::SOAP::SOAPStruct" or "CustomClass[]".  turn this String to a class if
    # we can.
    if mapped_class.is_a?(String)
      if /\[\]\Z/ =~ mapped_class
        # when '[]' is added, ignore this.
        mapped_class = nil
      else
        mapped_class = Mapping.class_from_name(mapped_class)
      end
    end
    mapped_class
  end
end


class SOAPMethodRequest < SOAPMethod
  attr_accessor :soapaction

  def SOAPMethodRequest.create_request(qname, *params)
    param_def = []
    param_value = []
    i = 0
    params.each do |param|
      param_name = "p#{i}"
      i += 1
      param_def << [IN, param_name, nil]
      param_value << [param_name, param]
    end
    param_def << [RETVAL, 'return', nil]
    o = new(qname, param_def)
    o.set_param(param_value)
    o
  end

  def initialize(qname, param_def = nil, soapaction = nil)
    super(qname, param_def)
    @soapaction = soapaction
  end

  def each
    input_params.each do |name|
      unless @inparam[name]
        raise ParameterError.new("parameter: #{name} was not given")
      end
      yield(name, @inparam[name])
    end
  end

  def dup
    req = self.class.new(@elename.dup, @param_def, @soapaction)
    req.encodingstyle = @encodingstyle
    req
  end

  def create_method_response(response_name = nil)
    response_name ||=
      XSD::QName.new(@elename.namespace, @elename.name + 'Response')
    SOAPMethodResponse.new(response_name, @param_def)
  end
end


class SOAPMethodResponse < SOAPMethod

  def initialize(qname, param_def = nil)
    super(qname, param_def)
    @retval = nil
  end

  def retval
    @retval
  end

  def retval=(retval)
    @retval = retval
    @retval.elename = @retval.elename.dup_name(@retval_name || 'return')
    retval.parent = self
    retval
  end

  def each
    if @retval_name and !@retval.is_a?(SOAPVoid)
      yield(@retval_name, @retval)
    end

    output_params.each do |name|
      unless @outparam[name]
        raise ParameterError.new("parameter: #{name} was not given")
      end
      yield(name, @outparam[name])
    end
  end
end


# To return(?) void explicitly.
#  def foo(input_var)
#    ...
#    return SOAP::RPC::SOAPVoid.new
#  end
class SOAPVoid < XSD::XSDAnySimpleType
  include SOAPBasetype
  extend SOAPModuleUtils
  Name = XSD::QName.new(Mapping::RubyCustomTypeNamespace, nil)

public
  def initialize()
    @elename = Name
    @id = nil
    @precedents = []
    @parent = nil
  end
end


end
end