actionwebservice 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/{ChangeLog → CHANGELOG} +20 -0
- data/README +45 -1
- data/Rakefile +12 -10
- data/TODO +8 -9
- data/lib/action_web_service.rb +10 -6
- data/lib/action_web_service/api.rb +1 -2
- data/lib/action_web_service/api/{abstract.rb → base.rb} +14 -71
- data/lib/action_web_service/base.rb +0 -3
- data/lib/action_web_service/client/base.rb +1 -12
- data/lib/action_web_service/client/soap_client.rb +49 -17
- data/lib/action_web_service/client/xmlrpc_client.rb +20 -15
- data/lib/action_web_service/container.rb +3 -85
- data/lib/action_web_service/{api/action_controller.rb → container/action_controller_container.rb} +2 -2
- data/lib/action_web_service/container/delegated_container.rb +87 -0
- data/lib/action_web_service/container/direct_container.rb +70 -0
- data/lib/action_web_service/dispatcher/abstract.rb +100 -102
- data/lib/action_web_service/dispatcher/action_controller_dispatcher.rb +199 -137
- data/lib/action_web_service/protocol.rb +1 -1
- data/lib/action_web_service/protocol/abstract.rb +14 -112
- data/lib/action_web_service/protocol/discovery.rb +37 -0
- data/lib/action_web_service/protocol/soap_protocol.rb +32 -458
- data/lib/action_web_service/protocol/xmlrpc_protocol.rb +29 -149
- data/lib/action_web_service/struct.rb +2 -5
- data/lib/action_web_service/test_invoke.rb +130 -0
- data/lib/action_web_service/vendor/ws.rb +4 -0
- data/lib/action_web_service/vendor/ws/common.rb +8 -0
- data/lib/action_web_service/vendor/ws/encoding.rb +3 -0
- data/lib/action_web_service/vendor/ws/encoding/abstract.rb +26 -0
- data/lib/action_web_service/vendor/ws/encoding/soap_rpc_encoding.rb +90 -0
- data/lib/action_web_service/vendor/ws/encoding/xmlrpc_encoding.rb +53 -0
- data/lib/action_web_service/vendor/ws/marshaling.rb +3 -0
- data/lib/action_web_service/vendor/ws/marshaling/abstract.rb +17 -0
- data/lib/action_web_service/vendor/ws/marshaling/soap_marshaling.rb +277 -0
- data/lib/action_web_service/vendor/ws/marshaling/xmlrpc_marshaling.rb +116 -0
- data/lib/action_web_service/vendor/ws/types.rb +162 -0
- data/test/abstract_client.rb +8 -11
- data/test/abstract_dispatcher.rb +370 -0
- data/test/abstract_unit.rb +1 -0
- data/test/api_test.rb +18 -1
- data/test/apis/auto_load_api.rb +3 -0
- data/test/apis/broken_auto_load_api.rb +2 -0
- data/test/client_soap_test.rb +16 -3
- data/test/client_xmlrpc_test.rb +16 -4
- data/test/container_test.rb +28 -8
- data/test/dispatcher_action_controller_soap_test.rb +106 -0
- data/test/dispatcher_action_controller_xmlrpc_test.rb +44 -0
- data/test/gencov +1 -1
- data/test/invocation_test.rb +39 -3
- data/test/run +4 -4
- data/test/test_invoke_test.rb +77 -0
- data/test/ws/abstract_encoding.rb +68 -0
- data/test/ws/abstract_unit.rb +13 -0
- data/test/ws/gencov +3 -0
- data/test/ws/run +5 -0
- data/test/ws/soap_marshaling_test.rb +91 -0
- data/test/ws/soap_rpc_encoding_test.rb +47 -0
- data/test/ws/types_test.rb +41 -0
- data/test/ws/xmlrpc_encoding_test.rb +34 -0
- metadata +48 -19
- data/lib/action_web_service/protocol/registry.rb +0 -55
- data/lib/action_web_service/support/signature.rb +0 -100
- data/test/abstract_soap.rb +0 -58
- data/test/dispatcher_action_controller_test.rb +0 -186
- data/test/protocol_registry_test.rb +0 -53
- data/test/protocol_soap_test.rb +0 -252
- data/test/protocol_xmlrpc_test.rb +0 -147
@@ -31,6 +31,7 @@ module ActionWebService # :nodoc:
|
|
31
31
|
@api = api
|
32
32
|
@handler_name = options[:handler_name]
|
33
33
|
@client = XMLRPC::Client.new2(endpoint_uri, options[:proxy], options[:timeout])
|
34
|
+
@marshaler = WS::Marshaling::XmlRpcMarshaler.new
|
34
35
|
end
|
35
36
|
|
36
37
|
protected
|
@@ -43,18 +44,21 @@ module ActionWebService # :nodoc:
|
|
43
44
|
|
44
45
|
def transform_outgoing_method_params(method_name, params)
|
45
46
|
info = @api.api_methods[method_name.to_sym]
|
46
|
-
|
47
|
-
|
48
|
-
if
|
49
|
-
raise(
|
50
|
-
|
51
|
-
|
47
|
+
expects = info[:expects]
|
48
|
+
expects_length = expects.nil?? 0 : expects.length
|
49
|
+
if expects_length != params.length
|
50
|
+
raise(ClientError, "API declares #{public_name(method_name)} to accept " +
|
51
|
+
"#{expects_length} parameters, but #{params.length} parameters " +
|
52
|
+
"were supplied")
|
52
53
|
end
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
54
|
+
params = params.dup
|
55
|
+
if expects_length > 0
|
56
|
+
i = 0
|
57
|
+
expects.each do |spec|
|
58
|
+
type_binding = @marshaler.register_type(spec)
|
59
|
+
info = WS::ParamInfo.create(spec, type_binding, i)
|
60
|
+
params[i] = @marshaler.marshal(WS::Param.new(params[i], info))
|
61
|
+
i += 1
|
58
62
|
end
|
59
63
|
end
|
60
64
|
params
|
@@ -62,10 +66,11 @@ module ActionWebService # :nodoc:
|
|
62
66
|
|
63
67
|
def transform_return_value(method_name, return_value)
|
64
68
|
info = @api.api_methods[method_name.to_sym]
|
65
|
-
return true unless
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
+
return true unless returns = info[:returns]
|
70
|
+
type_binding = @marshaler.register_type(returns[0])
|
71
|
+
info = WS::ParamInfo.create(returns[0], type_binding, 0)
|
72
|
+
info.name = 'return'
|
73
|
+
@marshaler.transform_inbound(WS::Param.new(return_value, info))
|
69
74
|
end
|
70
75
|
|
71
76
|
def public_name(method_name)
|
@@ -1,85 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
end
|
5
|
-
|
6
|
-
def self.append_features(base) # :nodoc:
|
7
|
-
super
|
8
|
-
base.extend(ClassMethods)
|
9
|
-
base.send(:include, ActionWebService::Container::InstanceMethods)
|
10
|
-
end
|
11
|
-
|
12
|
-
module ClassMethods
|
13
|
-
# Declares a web service that will provides access to the API of the given
|
14
|
-
# +object+. +object+ must be an ActionWebService::Base derivative.
|
15
|
-
#
|
16
|
-
# Web service object creation can either be _immediate_, where the object
|
17
|
-
# instance is given at class definition time, or _deferred_, where
|
18
|
-
# object instantiation is delayed until request time.
|
19
|
-
#
|
20
|
-
# ==== Immediate web service object example
|
21
|
-
#
|
22
|
-
# class ApiController < ApplicationController
|
23
|
-
# web_service_dispatching_mode :delegated
|
24
|
-
#
|
25
|
-
# web_service :person, PersonService.new
|
26
|
-
# end
|
27
|
-
#
|
28
|
-
# For deferred instantiation, a block should be given instead of an
|
29
|
-
# object instance. This block will be executed in controller instance
|
30
|
-
# context, so it can rely on controller instance variables being present.
|
31
|
-
#
|
32
|
-
# ==== Deferred web service object example
|
33
|
-
#
|
34
|
-
# class ApiController < ApplicationController
|
35
|
-
# web_service_dispatching_mode :delegated
|
36
|
-
#
|
37
|
-
# web_service(:person) { PersonService.new(@request.env) }
|
38
|
-
# end
|
39
|
-
def web_service(name, object=nil, &block)
|
40
|
-
if (object && block_given?) || (object.nil? && block.nil?)
|
41
|
-
raise(ContainerError, "either service, or a block must be given")
|
42
|
-
end
|
43
|
-
name = name.to_sym
|
44
|
-
if block_given?
|
45
|
-
info = { name => { :block => block } }
|
46
|
-
else
|
47
|
-
info = { name => { :object => object } }
|
48
|
-
end
|
49
|
-
write_inheritable_hash("web_services", info)
|
50
|
-
call_web_service_definition_callbacks(self, name, info)
|
51
|
-
end
|
52
|
-
|
53
|
-
# Whether this service contains a service with the given +name+
|
54
|
-
def has_web_service?(name)
|
55
|
-
web_services.has_key?(name.to_sym)
|
56
|
-
end
|
57
|
-
|
58
|
-
def web_services # :nodoc:
|
59
|
-
read_inheritable_attribute("web_services") || {}
|
60
|
-
end
|
61
|
-
|
62
|
-
def add_web_service_definition_callback(&block) # :nodoc:
|
63
|
-
write_inheritable_array("web_service_definition_callbacks", [block])
|
64
|
-
end
|
65
|
-
|
66
|
-
private
|
67
|
-
def call_web_service_definition_callbacks(container_class, web_service_name, service_info)
|
68
|
-
(read_inheritable_attribute("web_service_definition_callbacks") || []).each do |block|
|
69
|
-
block.call(container_class, web_service_name, service_info)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
module InstanceMethods # :nodoc:
|
75
|
-
def web_service_object(web_service_name)
|
76
|
-
info = self.class.web_services[web_service_name.to_sym]
|
77
|
-
unless info
|
78
|
-
raise(ContainerError, "no such web service '#{web_service_name}'")
|
79
|
-
end
|
80
|
-
service = info[:block]
|
81
|
-
service ? instance_eval(&service) : info[:object]
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
1
|
+
require 'action_web_service/container/direct_container'
|
2
|
+
require 'action_web_service/container/delegated_container'
|
3
|
+
require 'action_web_service/container/action_controller_container'
|
data/lib/action_web_service/{api/action_controller.rb → container/action_controller_container.rb}
RENAMED
@@ -1,5 +1,5 @@
|
|
1
1
|
module ActionWebService # :nodoc:
|
2
|
-
module
|
2
|
+
module Container # :nodoc:
|
3
3
|
module ActionController # :nodoc:
|
4
4
|
def self.append_features(base) # :nodoc:
|
5
5
|
base.class_eval do
|
@@ -36,7 +36,7 @@ module ActionWebService # :nodoc:
|
|
36
36
|
api_klass = options.delete(:api) || require_web_service_api(name)
|
37
37
|
class_eval do
|
38
38
|
define_method(name) do
|
39
|
-
|
39
|
+
create_web_service_client(api_klass, protocol, endpoint_uri, options)
|
40
40
|
end
|
41
41
|
protected name
|
42
42
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module ActionWebService # :nodoc:
|
2
|
+
module Container # :nodoc:
|
3
|
+
module Delegated # :nodoc:
|
4
|
+
class ContainerError < ActionWebServiceError # :nodoc:
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.append_features(base) # :nodoc:
|
8
|
+
super
|
9
|
+
base.extend(ClassMethods)
|
10
|
+
base.send(:include, ActionWebService::Container::Delegated::InstanceMethods)
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
# Declares a web service that will provides access to the API of the given
|
15
|
+
# +object+. +object+ must be an ActionWebService::Base derivative.
|
16
|
+
#
|
17
|
+
# Web service object creation can either be _immediate_, where the object
|
18
|
+
# instance is given at class definition time, or _deferred_, where
|
19
|
+
# object instantiation is delayed until request time.
|
20
|
+
#
|
21
|
+
# ==== Immediate web service object example
|
22
|
+
#
|
23
|
+
# class ApiController < ApplicationController
|
24
|
+
# web_service_dispatching_mode :delegated
|
25
|
+
#
|
26
|
+
# web_service :person, PersonService.new
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# For deferred instantiation, a block should be given instead of an
|
30
|
+
# object instance. This block will be executed in controller instance
|
31
|
+
# context, so it can rely on controller instance variables being present.
|
32
|
+
#
|
33
|
+
# ==== Deferred web service object example
|
34
|
+
#
|
35
|
+
# class ApiController < ApplicationController
|
36
|
+
# web_service_dispatching_mode :delegated
|
37
|
+
#
|
38
|
+
# web_service(:person) { PersonService.new(@request.env) }
|
39
|
+
# end
|
40
|
+
def web_service(name, object=nil, &block)
|
41
|
+
if (object && block_given?) || (object.nil? && block.nil?)
|
42
|
+
raise(ContainerError, "either service, or a block must be given")
|
43
|
+
end
|
44
|
+
name = name.to_sym
|
45
|
+
if block_given?
|
46
|
+
info = { name => { :block => block } }
|
47
|
+
else
|
48
|
+
info = { name => { :object => object } }
|
49
|
+
end
|
50
|
+
write_inheritable_hash("web_services", info)
|
51
|
+
call_web_service_definition_callbacks(self, name, info)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Whether this service contains a service with the given +name+
|
55
|
+
def has_web_service?(name)
|
56
|
+
web_services.has_key?(name.to_sym)
|
57
|
+
end
|
58
|
+
|
59
|
+
def web_services # :nodoc:
|
60
|
+
read_inheritable_attribute("web_services") || {}
|
61
|
+
end
|
62
|
+
|
63
|
+
def add_web_service_definition_callback(&block) # :nodoc:
|
64
|
+
write_inheritable_array("web_service_definition_callbacks", [block])
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
def call_web_service_definition_callbacks(container_class, web_service_name, service_info)
|
69
|
+
(read_inheritable_attribute("web_service_definition_callbacks") || []).each do |block|
|
70
|
+
block.call(container_class, web_service_name, service_info)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
module InstanceMethods # :nodoc:
|
76
|
+
def web_service_object(web_service_name)
|
77
|
+
info = self.class.web_services[web_service_name.to_sym]
|
78
|
+
unless info
|
79
|
+
raise(ContainerError, "no such web service '#{web_service_name}'")
|
80
|
+
end
|
81
|
+
service = info[:block]
|
82
|
+
service ? instance_eval(&service) : info[:object]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module ActionWebService # :nodoc:
|
2
|
+
module Container # :nodoc:
|
3
|
+
module Direct # :nodoc:
|
4
|
+
class ContainerError < ActionWebServiceError # :nodoc:
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.append_features(base) # :nodoc:
|
8
|
+
super
|
9
|
+
base.extend(ClassMethods)
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
# Attaches ActionWebService API +definition+ to the calling class.
|
14
|
+
#
|
15
|
+
# Action Controllers can have a default associated API, removing the need
|
16
|
+
# to call this method if you follow the Action Web Service naming conventions.
|
17
|
+
#
|
18
|
+
# A controller with a class name of GoogleSearchController will
|
19
|
+
# implicitly load <tt>app/apis/google_search_api.rb</tt>, and expect the
|
20
|
+
# API definition class to be named <tt>GoogleSearchAPI</tt> or
|
21
|
+
# <tt>GoogleSearchApi</tt>.
|
22
|
+
#
|
23
|
+
# ==== Service class example
|
24
|
+
#
|
25
|
+
# class MyService < ActionWebService::Base
|
26
|
+
# web_service_api MyAPI
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# class MyAPI < ActionWebService::API::Base
|
30
|
+
# ...
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# ==== Controller class example
|
34
|
+
#
|
35
|
+
# class MyController < ActionController::Base
|
36
|
+
# web_service_api MyAPI
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# class MyAPI < ActionWebService::API::Base
|
40
|
+
# ...
|
41
|
+
# end
|
42
|
+
def web_service_api(definition=nil)
|
43
|
+
if definition.nil?
|
44
|
+
read_inheritable_attribute("web_service_api")
|
45
|
+
else
|
46
|
+
if definition.is_a?(Symbol)
|
47
|
+
raise(ContainerError, "symbols can only be used for #web_service_api inside of a controller")
|
48
|
+
end
|
49
|
+
unless definition.respond_to?(:ancestors) && definition.ancestors.include?(ActionWebService::API::Base)
|
50
|
+
raise(ContainerError, "#{definition.to_s} is not a valid API definition")
|
51
|
+
end
|
52
|
+
write_inheritable_attribute("web_service_api", definition)
|
53
|
+
call_web_service_api_callbacks(self, definition)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def add_web_service_api_callback(&block) # :nodoc:
|
58
|
+
write_inheritable_array("web_service_api_callbacks", [block])
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
def call_web_service_api_callbacks(container_class, definition)
|
63
|
+
(read_inheritable_attribute("web_service_api_callbacks") || []).each do |block|
|
64
|
+
block.call(container_class, definition)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -12,138 +12,136 @@ module ActionWebService # :nodoc:
|
|
12
12
|
base.send(:include, ActionWebService::Dispatcher::InstanceMethods)
|
13
13
|
end
|
14
14
|
|
15
|
+
def self.layered_service_name(public_method_name) # :nodoc:
|
16
|
+
if public_method_name =~ /^([^\.]+)\.(.*)$/
|
17
|
+
$1
|
18
|
+
else
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
15
23
|
module InstanceMethods # :nodoc:
|
16
24
|
private
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
25
|
+
def invoke_web_service_request(protocol_request)
|
26
|
+
invocation = web_service_invocation(protocol_request)
|
27
|
+
case web_service_dispatching_mode
|
28
|
+
when :direct
|
29
|
+
web_service_direct_invoke(invocation)
|
30
|
+
when :delegated, :layered
|
31
|
+
web_service_delegated_invoke(invocation)
|
22
32
|
end
|
23
|
-
[protocol_request, protocol_response, bm.real, nil]
|
24
|
-
rescue Exception => e
|
25
|
-
protocol_response = prepare_exception_response(protocol_request, e)
|
26
|
-
[protocol_request, prepare_exception_response(protocol_request, e), nil, e]
|
27
33
|
end
|
28
34
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
dispatch_delegated_request(protocol_request)
|
35
|
+
def web_service_direct_invoke(invocation)
|
36
|
+
@method_params = invocation.method_ordered_params
|
37
|
+
return_value = self.__send__(invocation.api_method_name)
|
38
|
+
if invocation.api.has_api_method?(invocation.api_method_name)
|
39
|
+
returns = invocation.returns ? invocation.returns[0] : nil
|
35
40
|
else
|
36
|
-
|
41
|
+
returns = return_value.class
|
37
42
|
end
|
43
|
+
invocation.protocol.marshal_response(invocation.public_method_name, return_value, returns)
|
38
44
|
end
|
39
45
|
|
40
|
-
def
|
41
|
-
request = prepare_dispatch_request(protocol_request)
|
42
|
-
return_value = direct_invoke(request)
|
43
|
-
protocol_request.marshal(return_value)
|
44
|
-
end
|
45
|
-
|
46
|
-
def dispatch_delegated_request(protocol_request)
|
47
|
-
request = prepare_dispatch_request(protocol_request)
|
48
|
-
return_value = delegated_invoke(request)
|
49
|
-
protocol_request.marshal(return_value)
|
50
|
-
end
|
51
|
-
|
52
|
-
def direct_invoke(request)
|
53
|
-
return nil unless before_direct_invoke(request)
|
54
|
-
return_value = send(request.method_name)
|
55
|
-
after_direct_invoke(request)
|
56
|
-
return_value
|
57
|
-
end
|
58
|
-
|
59
|
-
def before_direct_invoke(request)
|
60
|
-
@method_params = request.params
|
61
|
-
end
|
62
|
-
|
63
|
-
def after_direct_invoke(request)
|
64
|
-
end
|
65
|
-
|
66
|
-
def delegated_invoke(request)
|
46
|
+
def web_service_delegated_invoke(invocation)
|
67
47
|
cancellation_reason = nil
|
68
|
-
|
69
|
-
return_value = web_service.perform_invocation(request.method_name, request.params) do |x|
|
48
|
+
return_value = invocation.service.perform_invocation(invocation.api_method_name, invocation.method_ordered_params) do |x|
|
70
49
|
cancellation_reason = x
|
71
50
|
end
|
72
51
|
if cancellation_reason
|
73
52
|
raise(DispatcherError, "request canceled: #{cancellation_reason}")
|
74
53
|
end
|
75
|
-
|
54
|
+
returns = invocation.returns ? invocation.returns[0] : nil
|
55
|
+
invocation.protocol.marshal_response(invocation.public_method_name, return_value, returns)
|
76
56
|
end
|
77
57
|
|
78
|
-
def
|
79
|
-
|
80
|
-
|
58
|
+
def web_service_invocation(request)
|
59
|
+
public_method_name = request.method_name
|
60
|
+
invocation = Invocation.new
|
61
|
+
invocation.protocol = request.protocol
|
62
|
+
invocation.service_name = request.service_name
|
63
|
+
if web_service_dispatching_mode == :layered
|
64
|
+
if request.method_name =~ /^([^\.]+)\.(.*)$/
|
65
|
+
public_method_name = $2
|
66
|
+
invocation.service_name = $1
|
67
|
+
end
|
68
|
+
end
|
69
|
+
invocation.public_method_name = public_method_name
|
81
70
|
case web_service_dispatching_mode
|
82
71
|
when :direct
|
83
|
-
api = self.class.web_service_api
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
72
|
+
invocation.api = self.class.web_service_api
|
73
|
+
invocation.service = self
|
74
|
+
when :delegated, :layered
|
75
|
+
invocation.service = web_service_object(invocation.service_name) rescue nil
|
76
|
+
unless invocation.service
|
77
|
+
raise(DispatcherError, "service #{invocation.service_name} not available")
|
78
|
+
end
|
79
|
+
invocation.api = invocation.service.class.web_service_api
|
88
80
|
end
|
89
|
-
|
90
|
-
|
91
|
-
if method_name
|
92
|
-
signature = api.api_methods[method_name]
|
93
|
-
protocol_request.type = Protocol::CheckedMessage
|
94
|
-
protocol_request.signature = signature[:expects]
|
95
|
-
protocol_request.return_signature = signature[:returns]
|
81
|
+
if invocation.api.has_public_api_method?(public_method_name)
|
82
|
+
invocation.api_method_name = invocation.api.api_method_name(public_method_name)
|
96
83
|
else
|
97
|
-
|
98
|
-
|
99
|
-
protocol_request.type = Protocol::UncheckedMessage
|
84
|
+
if invocation.api.default_api_method.nil?
|
85
|
+
raise(DispatcherError, "no such method '#{public_method_name}' on API #{invocation.api}")
|
100
86
|
else
|
101
|
-
|
87
|
+
invocation.api_method_name = invocation.api.default_api_method.to_s.to_sym
|
102
88
|
end
|
103
89
|
end
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
when :direct
|
119
|
-
if web_service_exception_reporting
|
120
|
-
return protocol_request.protocol.marshal_exception(exception)
|
121
|
-
end
|
122
|
-
when :delegated
|
123
|
-
web_service = web_service_object(protocol_request.web_service_name)
|
124
|
-
if web_service && web_service.class.web_service_exception_reporting
|
125
|
-
return protocol_request.protocol.marshal_exception(exception)
|
90
|
+
unless invocation.service.respond_to?(invocation.api_method_name)
|
91
|
+
raise(DispatcherError, "no such method '#{public_method_name}' on API #{invocation.api} (#{invocation.api_method_name})")
|
92
|
+
end
|
93
|
+
info = invocation.api.api_methods[invocation.api_method_name]
|
94
|
+
invocation.expects = info ? info[:expects] : nil
|
95
|
+
invocation.returns = info ? info[:returns] : nil
|
96
|
+
if invocation.expects
|
97
|
+
i = 0
|
98
|
+
invocation.method_ordered_params = request.method_params.map do |param|
|
99
|
+
if invocation.protocol.is_a?(Protocol::XmlRpc::XmlRpcProtocol)
|
100
|
+
marshaler = invocation.protocol.marshaler
|
101
|
+
decoded_param = WS::Encoding::XmlRpcDecodedParam.new(param.info.name, param.value)
|
102
|
+
marshaled_param = marshaler.typed_unmarshal(decoded_param, invocation.expects[i]) rescue nil
|
103
|
+
param = marshaled_param ? marshaled_param : param
|
126
104
|
end
|
105
|
+
i += 1
|
106
|
+
param.value
|
107
|
+
end
|
108
|
+
i = 0
|
109
|
+
params = []
|
110
|
+
invocation.expects.each do |spec|
|
111
|
+
type_binding = invocation.protocol.register_signature_type(spec)
|
112
|
+
info = WS::ParamInfo.create(spec, type_binding, i)
|
113
|
+
params << WS::Param.new(invocation.method_ordered_params[i], info)
|
114
|
+
i += 1
|
115
|
+
end
|
116
|
+
invocation.method_ws_params = params
|
117
|
+
invocation.method_named_params = {}
|
118
|
+
invocation.method_ws_params.each do |param|
|
119
|
+
invocation.method_named_params[param.info.name] = param.value
|
127
120
|
end
|
128
121
|
else
|
129
|
-
|
122
|
+
invocation.method_ordered_params = []
|
123
|
+
invocation.method_named_params = {}
|
130
124
|
end
|
131
|
-
|
132
|
-
|
125
|
+
if invocation.returns
|
126
|
+
invocation.returns.each do |spec|
|
127
|
+
invocation.protocol.register_signature_type(spec)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
invocation
|
133
131
|
end
|
134
132
|
|
135
|
-
class
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
133
|
+
class Invocation # :nodoc:
|
134
|
+
attr_accessor :protocol
|
135
|
+
attr_accessor :service_name
|
136
|
+
attr_accessor :api
|
137
|
+
attr_accessor :public_method_name
|
138
|
+
attr_accessor :api_method_name
|
139
|
+
attr_accessor :method_ordered_params
|
140
|
+
attr_accessor :method_named_params
|
141
|
+
attr_accessor :method_ws_params
|
142
|
+
attr_accessor :expects
|
143
|
+
attr_accessor :returns
|
144
|
+
attr_accessor :service
|
147
145
|
end
|
148
146
|
end
|
149
147
|
end
|