diff options
Diffstat (limited to 'lib/soap/rpc/driver.rb')
-rw-r--r-- | lib/soap/rpc/driver.rb | 239 |
1 files changed, 148 insertions, 91 deletions
diff --git a/lib/soap/rpc/driver.rb b/lib/soap/rpc/driver.rb index 0e59dde9be..028addc3eb 100644 --- a/lib/soap/rpc/driver.rb +++ b/lib/soap/rpc/driver.rb @@ -8,6 +8,7 @@ require 'soap/soap' require 'soap/mapping' +require 'soap/mapping/wsdlliteralregistry' require 'soap/rpc/rpc' require 'soap/rpc/proxy' require 'soap/rpc/element' @@ -43,42 +44,45 @@ class Driver __attr_proxy :options __attr_proxy :headerhandler + __attr_proxy :streamhandler __attr_proxy :test_loopback_response __attr_proxy :endpoint_url, true __attr_proxy :mapping_registry, true __attr_proxy :soapaction, true __attr_proxy :default_encodingstyle, true + __attr_proxy :generate_explicit_type, true + __attr_proxy :allow_unqualified_element, true def httpproxy - @servant.options["protocol.http.proxy"] + options["protocol.http.proxy"] end def httpproxy=(httpproxy) - @servant.options["protocol.http.proxy"] = httpproxy + options["protocol.http.proxy"] = httpproxy end def wiredump_dev - @servant.options["protocol.http.wiredump_dev"] + options["protocol.http.wiredump_dev"] end def wiredump_dev=(wiredump_dev) - @servant.options["protocol.http.wiredump_dev"] = wiredump_dev + options["protocol.http.wiredump_dev"] = wiredump_dev end def mandatorycharset - @servant.options["protocol.mandatorycharset"] + options["protocol.mandatorycharset"] end def mandatorycharset=(mandatorycharset) - @servant.options["protocol.mandatorycharset"] = mandatorycharset + options["protocol.mandatorycharset"] = mandatorycharset end def wiredump_file_base - @servant.options["protocol.wiredump_file_base"] + options["protocol.wiredump_file_base"] end def wiredump_file_base=(wiredump_file_base) - @servant.options["protocol.wiredump_file_base"] = wiredump_file_base + options["protocol.wiredump_file_base"] = wiredump_file_base end def initialize(endpoint_url, namespace, soapaction = nil) @@ -94,32 +98,59 @@ class Driver end def inspect - "#<#{self.class}:#{@servant.streamhandler.inspect}>" + "#<#{self.class}:#{@servant.inspect}>" end - def add_method(name, *params) - add_method_with_soapaction_as(name, name, @servant.soapaction, *params) + def add_rpc_method(name, *params) + param_def = create_rpc_param_def(params) + @servant.add_rpc_method(name, @servant.soapaction, name, param_def) end - def add_method_as(name, name_as, *params) - add_method_with_soapaction_as(name, name_as, @servant.soapaction, *params) + def add_rpc_method_as(name, name_as, *params) + param_def = create_rpc_param_def(params) + @servant.add_rpc_method(name_as, @servant.soapaction, name, param_def) end - def add_method_with_soapaction(name, soapaction, *params) - add_method_with_soapaction_as(name, name, soapaction, *params) + def add_rpc_method_with_soapaction(name, soapaction, *params) + param_def = create_rpc_param_def(params) + @servant.add_rpc_method(name, soapaction, name, param_def) end - def add_method_with_soapaction_as(name, name_as, soapaction, *params) - param_def = if params.size == 1 and params[0].is_a?(Array) - params[0] - else - SOAPMethod.create_param_def(params) - end - @servant.add_method(name_as, soapaction, name, param_def) + def add_rpc_method_with_soapaction_as(name, name_as, soapaction, *params) + param_def = create_rpc_param_def(params) + @servant.add_rpc_method(name_as, soapaction, name, param_def) + end + + # add_method is for shortcut of typical rpc/encoded method definition. + alias add_method add_rpc_method + alias add_method_as add_rpc_method_as + alias add_method_with_soapaction add_rpc_method_with_soapaction + alias add_method_with_soapaction_as add_rpc_method_with_soapaction_as + + def add_document_method(name, req_qname, res_qname) + param_def = create_document_param_def(name, req_qname, res_qname) + @servant.add_document_method(name, @servant.soapaction, name, param_def) + end + + def add_document_method_as(name, name_as, req_qname, res_qname) + param_def = create_document_param_def(name, req_qname, res_qname) + @servant.add_document_method(name_as, @servant.soapaction, name, param_def) + end + + def add_document_method_with_soapaction(name, soapaction, req_qname, + res_qname) + param_def = create_document_param_def(name, req_qname, res_qname) + @servant.add_document_method(name, soapaction, name, param_def) + end + + def add_document_method_with_soapaction_as(name, name_as, soapaction, + req_qname, res_qname) + param_def = create_document_param_def(name, req_qname, res_qname) + @servant.add_document_method(name_as, soapaction, name, param_def) end def reset_stream - @servant.streamhandler.reset + @servant.reset_stream end def invoke(headers, body) @@ -132,53 +163,62 @@ class Driver private + def create_rpc_param_def(params) + if params.size == 1 and params[0].is_a?(Array) + params[0] + else + SOAPMethod.create_param_def(params) + end + end + + def create_document_param_def(name, req_qname, res_qname) + [ + ['input', name, [nil, req_qname.namespace, req_qname.name]], + ['output', name, [nil, res_qname.namespace, res_qname.name]] + ] + end + def add_rpc_method_interface(name, param_def) @servant.add_rpc_method_interface(name, param_def) end + def add_document_method_interface(name, paramname) + @servant.add_document_method_interface(name, paramname) + end + class Servant__ - attr_reader :options - attr_reader :streamhandler - attr_reader :headerhandler attr_reader :proxy + attr_reader :options + attr_accessor :soapaction def initialize(host, endpoint_url, namespace) @host = host @namespace = namespace - @mapping_registry = nil @soapaction = nil - @wiredump_file_base = nil @options = setup_options - @streamhandler = HTTPPostStreamHandler.new(endpoint_url, - @options["protocol.http"] ||= ::SOAP::Property.new) - @headerhandler = Header::HandlerSet.new - @proxy = Proxy.new(@streamhandler, @soapaction) - @proxy.allow_unqualified_element = true + @wiredump_file_base = nil + @endpoint_url = endpoint_url + @proxy = Proxy.new(endpoint_url, @soapaction, @options) + end + + def inspect + "#<#{self.class}:#{@proxy.inspect}>" end def endpoint_url - @streamhandler.endpoint_url + @proxy.endpoint_url end def endpoint_url=(endpoint_url) - @streamhandler.endpoint_url = endpoint_url - @streamhandler.reset + @proxy.endpoint_url = endpoint_url end def mapping_registry - @mapping_registry + @proxy.mapping_registry end def mapping_registry=(mapping_registry) - @mapping_registry = mapping_registry - end - - def soapaction - @soapaction - end - - def soapaction=(soapaction) - @soapaction = soapaction + @proxy.mapping_registry = mapping_registry end def default_encodingstyle @@ -189,11 +229,42 @@ private @proxy.default_encodingstyle = encodingstyle end + def generate_explicit_type + @proxy.generate_explicit_type + end + + def generate_explicit_type=(generate_explicit_type) + @proxy.generate_explicit_type = generate_explicit_type + end + + def allow_unqualified_element + @proxy.allow_unqualified_element + end + + def allow_unqualified_element=(allow_unqualified_element) + @proxy.allow_unqualified_element = allow_unqualified_element + end + + def headerhandler + @proxy.headerhandler + end + + def streamhandler + @proxy.streamhandler + end + def test_loopback_response - @streamhandler.test_loopback_response + @proxy.test_loopback_response + end + + def reset_stream + @proxy.reset_stream end def invoke(headers, body) + if headers and !headers.is_a?(SOAPHeader) + headers = create_header(headers) + end set_wiredump_file_base(body.elename.name) env = @proxy.invoke(headers, body) if env.nil? @@ -205,39 +276,25 @@ private def call(name, *params) set_wiredump_file_base(name) - # Convert parameters: params array => SOAPArray => members array - params = Mapping.obj2soap(params, @mapping_registry).to_a - env = @proxy.call(call_headers, name, *params) - raise EmptyResponseError.new("Empty response.") unless env - receive_headers(env.header) - begin - @proxy.check_fault(env.body) - rescue SOAP::FaultError => e - Mapping.fault2exception(e) - end - - ret = env.body.response ? - Mapping.soap2obj(env.body.response, @mapping_registry) : nil - if env.body.outparams - outparams = env.body.outparams.collect { |outparam| - Mapping.soap2obj(outparam) - } - return [ret].concat(outparams) - else - return ret - end + @proxy.call(name, *params) end - def add_method(name_as, soapaction, name, param_def) + def add_rpc_method(name_as, soapaction, name, param_def) qname = XSD::QName.new(@namespace, name_as) - @proxy.add_method(qname, soapaction, name, param_def) + @proxy.add_rpc_method(qname, soapaction, name, param_def) add_rpc_method_interface(name, param_def) end + def add_document_method(name_as, soapaction, name, param_def) + qname = XSD::QName.new(@namespace, name_as) + @proxy.add_document_method(qname, soapaction, name, param_def) + add_document_method_interface(name, param_def) + end + def add_rpc_method_interface(name, param_def) param_names = [] i = 0 - @proxy.method[name].each_param_name(RPC::SOAPMethod::IN, + @proxy.operation[name].each_param_name(RPC::SOAPMethod::IN, RPC::SOAPMethod::INOUT) do |param_name| i += 1 param_names << "arg#{ i }" @@ -251,41 +308,41 @@ private @host.method(name) end - private - - def call_headers - headers = @headerhandler.on_outbound - if headers.empty? - nil - else - h = ::SOAP::SOAPHeader.new - headers.each do |header| - h.add(header.elename.name, header) - end - h - end + def add_document_method_interface(name, paramname) + @host.instance_eval <<-EOS + def #{ name }(param) + @servant.call(#{ name.dump }, param) + end + EOS + @host.method(name) end - def receive_headers(headers) - @headerhandler.on_inbound(headers) if headers - end + private def set_wiredump_file_base(name) if @wiredump_file_base - @streamhandler.wiredump_file_base = @wiredump_file_base + "_#{ name }" + @proxy.set_wiredump_file_base(@wiredump_file_base + "_#{ name }") + end + end + + def create_header(headers) + header = SOAPHeader.new() + headers.each do |content, mustunderstand, encodingstyle| + header.add(SOAPHeaderItem.new(content, mustunderstand, encodingstyle)) end + header end def setup_options if opt = Property.loadproperty(::SOAP::PropertyName) - opt = opt["client"] + opt = opt["client"] end opt ||= Property.new opt.add_hook("protocol.mandatorycharset") do |key, value| - @proxy.mandatorycharset = value + @proxy.mandatorycharset = value end opt.add_hook("protocol.wiredump_file_base") do |key, value| - @wiredump_file_base = value + @wiredump_file_base = value end opt["protocol.http.charset"] ||= XSD::Charset.encoding_label opt["protocol.http.proxy"] ||= Env::HTTP_PROXY |