diff options
Diffstat (limited to 'lib/soap/rpc/driver.rb')
-rw-r--r-- | lib/soap/rpc/driver.rb | 279 |
1 files changed, 175 insertions, 104 deletions
diff --git a/lib/soap/rpc/driver.rb b/lib/soap/rpc/driver.rb index 739c8774d4..e6ca3f39d3 100644 --- a/lib/soap/rpc/driver.rb +++ b/lib/soap/rpc/driver.rb @@ -12,6 +12,7 @@ require 'soap/rpc/rpc' require 'soap/rpc/proxy' require 'soap/rpc/element' require 'soap/streamHandler' +require 'soap/property' module SOAP @@ -19,91 +20,86 @@ module RPC class Driver -public class EmptyResponseError < Error; end - attr_accessor :mapping_registry - attr_accessor :soapaction - attr_reader :wiredump_dev - attr_reader :wiredump_file_base - attr_reader :streamhandler - - def initialize(endpoint_url, namespace, soapaction = nil) - @namespace = namespace - @mapping_registry = nil # for unmarshal - @soapaction = soapaction - @wiredump_dev = nil - @wiredump_file_base = nil - name = 'http_proxy' - @httpproxy = ENV[name] || ENV[name.upcase] - @streamhandler = HTTPPostStreamHandler.new(endpoint_url, @httpproxy, - XSD::Charset.encoding_label) - @proxy = Proxy.new(@streamhandler, @soapaction) - @proxy.allow_unqualified_element = true - end - - def inspect - "#<#{self.class}:#{@streamhandler.inspect}>" - end - - def endpoint_url - @streamhandler.endpoint_url + class << self + def __attr_proxy(symbol, assignable = false) + name = symbol.to_s + module_eval <<-EOD + def #{name} + @servant.#{name} + end + EOD + if assignable + module_eval <<-EOD + def #{name}=(rhs) + @servant.#{name} = rhs + end + EOD + end + end end - def endpoint_url=(endpoint_url) - @streamhandler.endpoint_url = endpoint_url - @streamhandler.reset - end + __attr_proxy :options + __attr_proxy :endpoint_url, true + __attr_proxy :mapping_registry, true + __attr_proxy :soapaction, true + __attr_proxy :default_encodingstyle, true - def wiredump_dev=(dev) - @wiredump_dev = dev - @streamhandler.wiredump_dev = @wiredump_dev - @streamhandler.reset + def httpproxy + @servant.options["protocol.http.proxy"] end - def wiredump_file_base=(base) - @wiredump_file_base = base + def httpproxy=(httpproxy) + @servant.options["protocol.http.proxy"] = httpproxy end - def httpproxy - @httpproxy + def wiredump_dev + @servant.options["protocol.http.wiredump_dev"] end - def httpproxy=(httpproxy) - @httpproxy = httpproxy - @streamhandler.proxy = @httpproxy - @streamhandler.reset + def wiredump_dev=(wiredump_dev) + @servant.options["protocol.http.wiredump_dev"] = wiredump_dev end def mandatorycharset - @proxy.mandatorycharset + @servant.options["protocol.mandatorycharset"] end def mandatorycharset=(mandatorycharset) - @proxy.mandatorycharset = mandatorycharset + @servant.options["protocol.mandatorycharset"] = mandatorycharset end - def default_encodingstyle - @proxy.default_encodingstyle + def wiredump_file_base + @servant.options["protocol.wiredump_file_base"] end - def default_encodingstyle=(encodingstyle) - @proxy.default_encodingstyle = encodingstyle + def wiredump_file_base=(wiredump_file_base) + @servant.options["protocol.wiredump_file_base"] = wiredump_file_base end + def initialize(endpoint_url, namespace, soapaction = nil) + @servant = Servant__.new(self, endpoint_url, namespace) + @servant.soapaction = soapaction + @proxy = @servant.proxy + if env_httpproxy = ::SOAP::Env::HTTP_PROXY + @servant.options["protocol.http.proxy"] = env_httpproxy + end + if env_no_proxy = ::SOAP::Env::NO_PROXY + @servant.options["protocol.http.no_proxy"] = env_no_proxy + end + end - ### - ## Method definition interfaces. - # - # params: [[param_def...]] or [paramname, paramname, ...] - # param_def: See proxy.rb. Sorry. + def inspect + "#<#{self.class}:#{@servant.streamhandler.inspect}>" + end def add_method(name, *params) - add_method_with_soapaction_as(name, name, @soapaction, *params) + add_method_with_soapaction_as(name, name, @servant.soapaction, *params) end def add_method_as(name, name_as, *params) - add_method_with_soapaction_as(name, name_as, @soapaction, *params) + add_method_with_soapaction_as(name, name_as, @servant.soapaction, *params) end def add_method_with_soapaction(name, soapaction, *params) @@ -116,72 +112,147 @@ public else SOAPMethod.create_param_def(params) end - qname = XSD::QName.new(@namespace, name_as) - @proxy.add_method(qname, soapaction, name, param_def) - add_rpc_method_interface(name, param_def) + @servant.add_method(name_as, soapaction, name, param_def) end + def reset_stream + @servant.streamhandler.reset + end - ### - ## Driving interface. - # def invoke(headers, body) - if @wiredump_file_base - @streamhandler.wiredump_file_base = - @wiredump_file_base + '_' << body.elename.name - end - @proxy.invoke(headers, body) + @servant.invoke(headers, body) end def call(name, *params) - # Convert parameters: params array => SOAPArray => members array - params = Mapping.obj2soap(params, @mapping_registry).to_a - if @wiredump_file_base - @streamhandler.wiredump_file_base = @wiredump_file_base + '_' << name + @servant.call(name, *params) + end + +private + + def add_rpc_method_interface(name, param_def) + @servant.add_rpc_method_interface(name, param_def) + end + + class Servant__ + attr_reader :options + attr_reader :streamhandler + attr_reader :proxy + + def initialize(host, endpoint_url, namespace) + @host = host + @namespace = namespace + @mapping_registry = nil + @soapaction = nil + @wiredump_file_base = nil + @options = ::SOAP::Property.new + set_options + @streamhandler = HTTPPostStreamHandler.new(endpoint_url, + @options["protocol.http"] ||= ::SOAP::Property.new) + @proxy = Proxy.new(@streamhandler, @soapaction) + @proxy.allow_unqualified_element = true end - # Then, call @proxy.call like the following. - header, body = @proxy.call(nil, name, *params) - unless body - raise EmptyResponseError.new("Empty response.") + def endpoint_url + @streamhandler.endpoint_url end - begin - @proxy.check_fault(body) - rescue SOAP::FaultError => e - Mapping.fault2exception(e) + def endpoint_url=(endpoint_url) + @streamhandler.endpoint_url = endpoint_url + @streamhandler.reset end - ret = body.response ? Mapping.soap2obj(body.response, @mapping_registry) : nil - if body.outparams - outparams = body.outparams.collect { |outparam| Mapping.soap2obj(outparam) } - return [ret].concat(outparams) - else - return ret + def mapping_registry + @mapping_registry end - end - def reset_stream - @streamhandler.reset - end + def mapping_registry=(mapping_registry) + @mapping_registry = mapping_registry + end -private + def soapaction + @soapaction + end - def add_rpc_method_interface(name, param_def) - param_names = [] - i = 0 - @proxy.method[name].each_param_name(RPC::SOAPMethod::IN, - RPC::SOAPMethod::INOUT) do |param_name| - i += 1 - param_names << "arg#{ i }" - end - - callparam = (param_names.collect { |pname| ", " + pname }).join - self.instance_eval <<-EOS - def #{ name }(#{ param_names.join(", ") }) - call("#{ name }"#{ callparam }) + def soapaction=(soapaction) + @soapaction = soapaction + end + + def default_encodingstyle + @proxy.default_encodingstyle + end + + def default_encodingstyle=(encodingstyle) + @proxy.default_encodingstyle = encodingstyle + end + + def invoke(headers, body) + set_wiredump_file_base(body.elename.name) + @proxy.invoke(headers, body) + end + + def call(name, *params) + set_wiredump_file_base(name) + # Convert parameters: params array => SOAPArray => members array + params = Mapping.obj2soap(params, @mapping_registry).to_a + header, body = @proxy.call(nil, name, *params) + raise EmptyResponseError.new("Empty response.") unless body + begin + @proxy.check_fault(body) + rescue SOAP::FaultError => e + Mapping.fault2exception(e) end - EOS + + ret = body.response ? + Mapping.soap2obj(body.response, @mapping_registry) : nil + if body.outparams + outparams = body.outparams.collect { |outparam| + Mapping.soap2obj(outparam) + } + return [ret].concat(outparams) + else + return ret + end + end + + def add_method(name_as, soapaction, name, param_def) + qname = XSD::QName.new(@namespace, name_as) + @proxy.add_method(qname, soapaction, name, param_def) + add_rpc_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, + RPC::SOAPMethod::INOUT) do |param_name| + i += 1 + param_names << "arg#{ i }" + end + callparam = (param_names.collect { |pname| ", " + pname }).join + @host.instance_eval <<-EOS + def #{ name }(#{ param_names.join(", ") }) + @servant.call(#{ name.dump }#{ callparam }) + end + EOS + end + + private + + def set_wiredump_file_base(name) + if @wiredump_file_base + @streamhandler.wiredump_file_base = @wiredump_file_base + "_#{ name }" + end + end + + def set_options + @options.add_hook("protocol.mandatorycharset") do |key, value| + @proxy.mandatorycharset = value + end + @options.add_hook("protocol.wiredump_file_base") do |key, value| + @wiredump_file_base = value + end + @options["protocol.http.charset"] = XSD::Charset.encoding_label + end end end |