diff options
Diffstat (limited to 'lib/soap/rpc/driver.rb')
-rw-r--r-- | lib/soap/rpc/driver.rb | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/lib/soap/rpc/driver.rb b/lib/soap/rpc/driver.rb new file mode 100644 index 0000000000..76fd14e34b --- /dev/null +++ b/lib/soap/rpc/driver.rb @@ -0,0 +1,189 @@ +=begin +SOAP4R - SOAP RPC driver +Copyright (C) 2000, 2001, 2003 NAKAMURA, Hiroshi. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PRATICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 675 Mass +Ave, Cambridge, MA 02139, USA. +=end + + +require 'soap/soap' +require 'soap/mapping' +require 'soap/rpc/rpc' +require 'soap/rpc/proxy' +require 'soap/rpc/element' +require 'soap/streamHandler' + + +module SOAP +module RPC + + +class Driver +public + class EmptyResponseError < Error; end + + attr_accessor :mapping_registry + attr_accessor :soapaction + attr_reader :endpoint_url + attr_reader :wiredump_dev + attr_reader :wiredump_file_base + attr_reader :httpproxy + + def initialize(endpoint_url, namespace, soapaction = nil) + @endpoint_url = endpoint_url + @namespace = namespace + @mapping_registry = nil # for unmarshal + @soapaction = soapaction + @wiredump_dev = nil + @wiredump_file_base = nil + @httpproxy = ENV['httpproxy'] || ENV['HTTP_PROXY'] + @handler = HTTPPostStreamHandler.new(@endpoint_url, @httpproxy, + XSD::Charset.encoding_label) + @proxy = Proxy.new(@handler, @soapaction) + @proxy.allow_unqualified_element = true + end + + def endpoint_url=(endpoint_url) + @endpoint_url = endpoint_url + if @handler + @handler.endpoint_url = @endpoint_url + @handler.reset + end + end + + def wiredump_dev=(dev) + @wiredump_dev = dev + if @handler + @handler.wiredump_dev = @wiredump_dev + @handler.reset + end + end + + def wiredump_file_base=(base) + @wiredump_file_base = base + end + + def httpproxy=(httpproxy) + @httpproxy = httpproxy + if @handler + @handler.proxy = @httpproxy + @handler.reset + end + end + + def default_encodingstyle + @proxy.default_encodingstyle + end + + def default_encodingstyle=(encodingstyle) + @proxy.default_encodingstyle = encodingstyle + end + + + ### + ## Method definition interfaces. + # + # params: [[param_def...]] or [paramname, paramname, ...] + # param_def: See proxy.rb. Sorry. + + def add_method(name, *params) + add_method_with_soapaction_as(name, name, @soapaction, *params) + end + + def add_method_as(name, name_as, *params) + add_method_with_soapaction_as(name, name_as, @soapaction, *params) + end + + def add_method_with_soapaction(name, soapaction, *params) + add_method_with_soapaction_as(name, name, soapaction, *params) + 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 + qname = XSD::QName.new(@namespace, name_as) + @proxy.add_method(qname, soapaction, name, param_def) + add_rpc_method_interface(name, param_def) + end + + + ### + ## Driving interface. + # + def invoke(headers, body) + if @wiredump_file_base + @handler.wiredump_file_base = + @wiredump_file_base + '_' << body.elename.name + end + @proxy.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 + @handler.wiredump_file_base = @wiredump_file_base + '_' << name + end + + # Then, call @proxy.call like the following. + header, body = @proxy.call(nil, name, *params) + unless body + raise EmptyResponseError.new("Empty response.") + end + + begin + @proxy.check_fault(body) + rescue SOAP::FaultError => e + Mapping.fault2exception(e) + 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 + end + end + + def reset_stream + @handler.reset + end + +private + + 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 }) + end + EOS + end +end + + +end +end |