| Class | SOAP::WSDLDriver::Servant__ |
| In: |
lib/soap/wsdlDriver.rb
|
| Parent: | Object |
| allow_unqualified_element | [RW] | |
| default_encodingstyle | [RW] | |
| generate_explicit_type | [RW] | |
| mapping_registry | [RW] | |
| options | [R] | |
| port | [R] | |
| soapaction | [RW] | |
| wsdl_mapping_registry | [RW] |
# File lib/soap/wsdlDriver.rb, line 268
268: def initialize(host, wsdl, port, logdev)
269: @host = host
270: @wsdl = wsdl
271: @port = port
272: @logdev = logdev
273: @soapaction = nil
274: @options = setup_options
275: @default_encodingstyle = nil
276: @allow_unqualified_element = nil
277: @generate_explicit_type = false
278: @mapping_registry = nil # for rpc unmarshal
279: @wsdl_mapping_registry = nil # for rpc marshal
280: @wiredump_file_base = nil
281: @mandatorycharset = nil
282: @wsdl_elements = @wsdl.collect_elements
283: @wsdl_types = @wsdl.collect_complextypes + @wsdl.collect_simpletypes
284: @rpc_decode_typemap = @wsdl_types +
285: @wsdl.soap_rpc_complextypes(port.find_binding)
286: @wsdl_mapping_registry = Mapping::WSDLEncodedRegistry.new(
287: @rpc_decode_typemap)
288: @doc_mapper = Mapping::WSDLLiteralRegistry.new(
289: @wsdl_types, @wsdl_elements)
290: endpoint_url = @port.soap_address.location
291: # Convert a map which key is QName, to a Hash which key is String.
292: @operation = {}
293: @port.inputoperation_map.each do |op_name, op_info|
294: orgname = op_name.name
295: name = XSD::CodeGen::GenSupport.safemethodname(orgname)
296: @operation[name] = @operation[orgname] = op_info
297: add_method_interface(op_info)
298: end
299: @proxy = ::SOAP::RPC::Proxy.new(endpoint_url, @soapaction, @options)
300: end
req_header: [[element, mustunderstand, encodingstyle(QName/String)], …] req_body: SOAPBasetype/SOAPCompoundtype
# File lib/soap/wsdlDriver.rb, line 363
363: def document_send(name, header_obj, body_obj)
364: set_wiredump_file_base(name)
365: unless op_info = @operation[name]
366: raise RuntimeError, "method: #{name} not defined"
367: end
368: req_header = header_obj ? header_from_obj(header_obj, op_info) : nil
369: req_body = body_from_obj(body_obj, op_info)
370: opt = create_options({
371: :soapaction => op_info.soapaction || @soapaction,
372: :decode_typemap => @wsdl_types})
373: env = @proxy.invoke(req_header, req_body, opt)
374: raise EmptyResponseError unless env
375: if env.body.fault
376: raise ::SOAP::FaultError.new(env.body.fault)
377: end
378: res_body_obj = env.body.response ?
379: Mapping.soap2obj(env.body.response, @mapping_registry) : nil
380: return env.header, res_body_obj
381: end
# File lib/soap/wsdlDriver.rb, line 310
310: def endpoint_url=(endpoint_url)
311: @proxy.endpoint_url = endpoint_url
312: end
# File lib/soap/wsdlDriver.rb, line 302
302: def inspect
303: "#<#{self.class}:#{@proxy.inspect}>"
304: end
# File lib/soap/wsdlDriver.rb, line 330
330: def rpc_call(name, *values)
331: set_wiredump_file_base(name)
332: unless op_info = @operation[name]
333: raise RuntimeError, "method: #{name} not defined"
334: end
335: req_header = create_request_header
336: req_body = create_request_body(op_info, *values)
337: reqopt = create_options({
338: :soapaction => op_info.soapaction || @soapaction})
339: resopt = create_options({
340: :decode_typemap => @rpc_decode_typemap})
341: env = @proxy.route(req_header, req_body, reqopt, resopt)
342: raise EmptyResponseError unless env
343: receive_headers(env.header)
344: begin
345: @proxy.check_fault(env.body)
346: rescue ::SOAP::FaultError => e
347: Mapping.fault2exception(e)
348: end
349: ret = env.body.response ?
350: Mapping.soap2obj(env.body.response, @mapping_registry) : nil
351: if env.body.outparams
352: outparams = env.body.outparams.collect { |outparam|
353: Mapping.soap2obj(outparam)
354: }
355: return [ret].concat(outparams)
356: else
357: return ret
358: end
359: end
# File lib/soap/wsdlDriver.rb, line 322
322: def test_loopback_response
323: @proxy.test_loopback_response
324: end
# File lib/soap/wsdlDriver.rb, line 550
550: def add_document_method_interface(name, parts_names)
551: ::SOAP::Mapping.define_singleton_method(@host, name) do |h, b|
552: @servant.document_send(name, h, b)
553: end
554: @host.method(name)
555: end
# File lib/soap/wsdlDriver.rb, line 519
519: def add_method_interface(op_info)
520: name = XSD::CodeGen::GenSupport.safemethodname(op_info.op_name.name)
521: orgname = op_info.op_name.name
522: parts_names = op_info.bodyparts.collect { |part| part.name }
523: case op_info.style
524: when :document
525: if orgname != name and orgname.capitalize == name.capitalize
526: add_document_method_interface(orgname, parts_names)
527: end
528: add_document_method_interface(name, parts_names)
529: when :rpc
530: if orgname != name and orgname.capitalize == name.capitalize
531: add_rpc_method_interface(orgname, parts_names)
532: end
533: add_rpc_method_interface(name, parts_names)
534: else
535: raise RuntimeError.new("unknown style: #{op_info.style}")
536: end
537: end
# File lib/soap/wsdlDriver.rb, line 539
539: def add_rpc_method_interface(name, parts_names)
540: ::SOAP::Mapping.define_singleton_method(@host, name) do |*arg|
541: unless arg.size == parts_names.size
542: raise ArgumentError.new(
543: "wrong number of arguments (#{arg.size} for #{parts_names.size})")
544: end
545: @servant.rpc_call(name, *arg)
546: end
547: @host.method(name)
548: end
# File lib/soap/wsdlDriver.rb, line 485
485: def body_from_obj(obj, op_info)
486: if obj.is_a?(SOAPBody)
487: obj
488: elsif op_info.bodyparts.empty?
489: if obj.nil?
490: nil
491: else
492: raise RuntimeError.new("no body found in schema")
493: end
494: elsif op_info.bodyparts.size == 1
495: part = op_info.bodyparts[0]
496: ele = bodyitem_from_obj(obj, part.element || part.type)
497: SOAPBody.new(ele)
498: else
499: body = SOAPBody.new
500: op_info.bodyparts.each do |part|
501: child = Mapping.get_attribute(obj, part.name)
502: ele = bodyitem_from_obj(child, part.element || part.type)
503: body.add(ele.elename.name, ele)
504: end
505: body
506: end
507: end
# File lib/soap/wsdlDriver.rb, line 509
509: def bodyitem_from_obj(obj, name)
510: if obj.nil?
511: SOAPElement.new(name)
512: elsif obj.is_a?(SOAPElement)
513: obj
514: else
515: Mapping.obj2soap(obj, @doc_mapper, name)
516: end
517: end
# File lib/soap/wsdlDriver.rb, line 440
440: def create_method_obj(names, params)
441: o = Object.new
442: idx = 0
443: while idx < params.length
444: o.instance_variable_set('@' + names[idx], params[idx])
445: idx += 1
446: end
447: o
448: end
# File lib/soap/wsdlDriver.rb, line 422
422: def create_method_struct(op_info, *params)
423: parts_names = op_info.bodyparts.collect { |part| part.name }
424: obj = create_method_obj(parts_names, params)
425: method = Mapping.obj2soap(obj, @wsdl_mapping_registry, op_info.op_name)
426: if method.members.size != parts_names.size
427: new_method = SOAPStruct.new
428: method.each do |key, value|
429: if parts_names.include?(key)
430: new_method.add(key, value)
431: end
432: end
433: method = new_method
434: end
435: method.elename = op_info.op_name
436: method.type = XSD::QName.new # Request should not be typed.
437: method
438: end
# File lib/soap/wsdlDriver.rb, line 385
385: def create_options(hash = nil)
386: opt = {}
387: opt[:default_encodingstyle] = @default_encodingstyle
388: opt[:allow_unqualified_element] = @allow_unqualified_element
389: opt[:generate_explicit_type] = @generate_explicit_type
390: opt.update(hash) if hash
391: opt
392: end
# File lib/soap/wsdlDriver.rb, line 417
417: def create_request_body(op_info, *values)
418: method = create_method_struct(op_info, *values)
419: SOAPBody.new(method)
420: end
# File lib/soap/wsdlDriver.rb, line 400
400: def create_request_header
401: headers = @proxy.headerhandler.on_outbound
402: if headers.empty?
403: nil
404: else
405: h = SOAPHeader.new
406: headers.each do |header|
407: h.add(header.elename.name, header)
408: end
409: h
410: end
411: end
# File lib/soap/wsdlDriver.rb, line 450
450: def header_from_obj(obj, op_info)
451: if obj.is_a?(SOAPHeader)
452: obj
453: elsif op_info.headerparts.empty?
454: if obj.nil?
455: nil
456: else
457: raise RuntimeError.new("no header definition in schema: #{obj}")
458: end
459: elsif op_info.headerparts.size == 1
460: part = op_info.headerparts[0]
461: header = SOAPHeader.new()
462: header.add(headeritem_from_obj(obj, part.element || part.eletype))
463: header
464: else
465: header = SOAPHeader.new()
466: op_info.headerparts.each do |part|
467: child = Mapping.get_attribute(obj, part.name)
468: ele = headeritem_from_obj(child, part.element || part.eletype)
469: header.add(part.name, ele)
470: end
471: header
472: end
473: end
# File lib/soap/wsdlDriver.rb, line 475
475: def headeritem_from_obj(obj, name)
476: if obj.nil?
477: SOAPElement.new(name)
478: elsif obj.is_a?(SOAPHeaderItem)
479: obj
480: else
481: Mapping.obj2soap(obj, @doc_mapper, name)
482: end
483: end
# File lib/soap/wsdlDriver.rb, line 413
413: def receive_headers(headers)
414: @proxy.headerhandler.on_inbound(headers) if headers
415: end
# File lib/soap/wsdlDriver.rb, line 394
394: def set_wiredump_file_base(name)
395: if @wiredump_file_base
396: @proxy.set_wiredump_file_base(@wiredump_file_base + "_#{name}")
397: end
398: end
# File lib/soap/wsdlDriver.rb, line 557
557: def setup_options
558: if opt = Property.loadproperty(::SOAP::PropertyName)
559: opt = opt["client"]
560: end
561: opt ||= Property.new
562: opt.add_hook("protocol.mandatorycharset") do |key, value|
563: @mandatorycharset = value
564: end
565: opt.add_hook("protocol.wiredump_file_base") do |key, value|
566: @wiredump_file_base = value
567: end
568: opt["protocol.http.charset"] ||= XSD::Charset.xml_encoding_label
569: opt["protocol.http.proxy"] ||= Env::HTTP_PROXY
570: opt["protocol.http.no_proxy"] ||= Env::NO_PROXY
571: opt
572: end