diff options
author | Leon Breedt <bitserf@gmail.com> | 2005-02-19 08:29:42 +0000 |
---|---|---|
committer | Leon Breedt <bitserf@gmail.com> | 2005-02-19 08:29:42 +0000 |
commit | 418d487020d24e69b528fdbedfecb20a87f99fcb (patch) | |
tree | 1956d6982123df1638bdef8274dff50ae71b25c2 /actionwebservice/lib/action_web_service/client/soap_client.rb | |
parent | e7499638d06023ae493d14ec1dc4f58bad8ac168 (diff) | |
download | rails-418d487020d24e69b528fdbedfecb20a87f99fcb.tar.gz rails-418d487020d24e69b528fdbedfecb20a87f99fcb.tar.bz2 rails-418d487020d24e69b528fdbedfecb20a87f99fcb.zip |
refactoring:
* move dispatching out of the Container into Dispatcher, it makes more sense
for Container to only contain the list of web services defined
in it.
* collapse Wsdl and ActionController "routers" into
an ActionController-specific module, no advantage
to having them seperate as they were quite tightly
coupled. rename to Dispatcher, to avoi
confusion with Routing.
* add a "_thing" suffix to concept-specific filenames. this is so that
we don't end up with many soap.rb files, for example.
* remove "virtual invocation" support. adds complexity, and it doesn't
seem to add any value.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@679 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionwebservice/lib/action_web_service/client/soap_client.rb')
-rw-r--r-- | actionwebservice/lib/action_web_service/client/soap_client.rb | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/actionwebservice/lib/action_web_service/client/soap_client.rb b/actionwebservice/lib/action_web_service/client/soap_client.rb new file mode 100644 index 0000000000..3557f88594 --- /dev/null +++ b/actionwebservice/lib/action_web_service/client/soap_client.rb @@ -0,0 +1,87 @@ +require 'soap/rpc/driver' +require 'uri' + +module ActionWebService # :nodoc: + module Client # :nodoc: + + # Implements SOAP client support (using RPC encoding for the messages). + # + # ==== Example Usage + # + # class PersonAPI < ActionWebService::API::Base + # api_method :find_all, :returns => [[Person]] + # end + # + # soap_client = ActionWebService::Client::Soap.new(PersonAPI, "http://...") + # persons = soap_client.find_all + # + class Soap < Base + + # Creates a new web service client using the SOAP RPC protocol. + # + # +api+ must be an ActionWebService::API::Base derivative, and + # +endpoint_uri+ must point at the relevant URL to which protocol requests + # will be sent with HTTP POST. + # + # Valid options: + # [<tt>:service_name</tt>] If the remote server has used a custom +wsdl_service_name+ + # option, you must specify it here + def initialize(api, endpoint_uri, options={}) + super(api, endpoint_uri) + @service_name = options[:service_name] || 'ActionWebService' + @namespace = "urn:#{@service_name}" + @mapper = ActionWebService::Protocol::Soap::SoapMapper.new(@namespace) + @protocol = ActionWebService::Protocol::Soap::SoapProtocol.new(@mapper) + @soap_action_base = options[:soap_action_base] + @soap_action_base ||= URI.parse(endpoint_uri).path + @driver = create_soap_rpc_driver(api, endpoint_uri) + end + + protected + def perform_invocation(method_name, args) + @driver.send(method_name, *args) + end + + def soap_action(method_name) + "#{@soap_action_base}/#{method_name}" + end + + private + def create_soap_rpc_driver(api, endpoint_uri) + @mapper.map_api(api) + driver = SoapDriver.new(endpoint_uri, nil) + driver.mapping_registry = @mapper.registry + api.api_methods.each do |name, info| + public_name = api.public_api_method_name(name) + qname = XSD::QName.new(@namespace, public_name) + action = soap_action(public_name) + expects = info[:expects] + returns = info[:returns] + param_def = [] + i = 1 + if expects + expects.each do |klass| + param_name = klass.is_a?(Hash) ? klass.keys[0] : "param#{i}" + mapping = @mapper.lookup(klass) + param_def << ['in', param_name, mapping.registry_mapping] + i += 1 + end + end + if returns + mapping = @mapper.lookup(returns[0]) + param_def << ['retval', 'return', mapping.registry_mapping] + end + driver.add_method(qname, action, name.to_s, param_def) + end + driver + end + + class SoapDriver < SOAP::RPC::Driver # :nodoc: + def add_method(qname, soapaction, name, param_def) + @proxy.add_rpc_method(qname, soapaction, name, param_def) + add_rpc_method_interface(name, param_def) + end + end + end + end +end |