aboutsummaryrefslogtreecommitdiffstats
path: root/actionwebservice/lib/action_web_service/dispatcher
diff options
context:
space:
mode:
authorLeon Breedt <bitserf@gmail.com>2005-03-28 03:20:13 +0000
committerLeon Breedt <bitserf@gmail.com>2005-03-28 03:20:13 +0000
commit594063f23cf8e7cecd24329e801992784f420b55 (patch)
treed52e9a6fc0521d51fcc3875162adf0411ee6caa0 /actionwebservice/lib/action_web_service/dispatcher
parent439a216dcb65ac83d86ca04bb898e1797a87ce70 (diff)
downloadrails-594063f23cf8e7cecd24329e801992784f420b55.tar.gz
rails-594063f23cf8e7cecd24329e801992784f420b55.tar.bz2
rails-594063f23cf8e7cecd24329e801992784f420b55.zip
generalize casting code to be used by both SOAP and XML-RPC (previously only XML-RPC). switch
to better model for API methods, and improve the ability to generate protocol requests/response, will be required by upcoming scaffolding. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1030 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionwebservice/lib/action_web_service/dispatcher')
-rw-r--r--actionwebservice/lib/action_web_service/dispatcher/abstract.rb80
-rw-r--r--actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb37
2 files changed, 44 insertions, 73 deletions
diff --git a/actionwebservice/lib/action_web_service/dispatcher/abstract.rb b/actionwebservice/lib/action_web_service/dispatcher/abstract.rb
index b63fe65ce1..4c184fb140 100644
--- a/actionwebservice/lib/action_web_service/dispatcher/abstract.rb
+++ b/actionwebservice/lib/action_web_service/dispatcher/abstract.rb
@@ -34,30 +34,30 @@ module ActionWebService # :nodoc:
def web_service_direct_invoke(invocation)
@method_params = invocation.method_ordered_params
- arity = method(invocation.api_method_name).arity rescue 0
+ arity = method(invocation.api_method.name).arity rescue 0
if arity < 0 || arity > 0
- return_value = self.__send__(invocation.api_method_name, *@method_params)
+ return_value = self.__send__(invocation.api_method.name, *@method_params)
else
- return_value = self.__send__(invocation.api_method_name)
+ return_value = self.__send__(invocation.api_method.name)
end
- if invocation.api.has_api_method?(invocation.api_method_name)
- returns = invocation.returns ? invocation.returns[0] : nil
+ if invocation.api.has_api_method?(invocation.api_method.name)
+ api_method = invocation.api_method
else
- returns = return_value.class
+ api_method = invocation.api_method.dup
+ api_method.instance_eval{ @returns = [ return_value.class ] }
end
- invocation.protocol.marshal_response(invocation.public_method_name, return_value, returns)
+ invocation.protocol.marshal_response(api_method, return_value)
end
def web_service_delegated_invoke(invocation)
cancellation_reason = nil
- return_value = invocation.service.perform_invocation(invocation.api_method_name, invocation.method_ordered_params) do |x|
+ return_value = invocation.service.perform_invocation(invocation.api_method.name, invocation.method_ordered_params) do |x|
cancellation_reason = x
end
if cancellation_reason
raise(DispatcherError, "request canceled: #{cancellation_reason}")
end
- returns = invocation.returns ? invocation.returns[0] : nil
- invocation.protocol.marshal_response(invocation.public_method_name, return_value, returns)
+ invocation.protocol.marshal_response(invocation.api_method, return_value)
end
def web_service_invocation(request)
@@ -71,7 +71,6 @@ module ActionWebService # :nodoc:
invocation.service_name = $1
end
end
- invocation.public_method_name = public_method_name
case web_service_dispatching_mode
when :direct
invocation.api = self.class.web_service_api
@@ -83,54 +82,29 @@ module ActionWebService # :nodoc:
end
invocation.api = invocation.service.class.web_service_api
end
+ request.api = invocation.api
if invocation.api.has_public_api_method?(public_method_name)
- invocation.api_method_name = invocation.api.api_method_name(public_method_name)
+ invocation.api_method = invocation.api.public_api_method_instance(public_method_name)
else
if invocation.api.default_api_method.nil?
raise(DispatcherError, "no such method '#{public_method_name}' on API #{invocation.api}")
else
- invocation.api_method_name = invocation.api.default_api_method.to_s.to_sym
+ invocation.api_method = invocation.api.default_api_method_instance
end
end
- unless invocation.service.respond_to?(invocation.api_method_name)
- raise(DispatcherError, "no such method '#{public_method_name}' on API #{invocation.api} (#{invocation.api_method_name})")
+ unless invocation.service.respond_to?(invocation.api_method.name)
+ raise(DispatcherError, "no such method '#{public_method_name}' on API #{invocation.api} (#{invocation.api_method.name})")
end
- info = invocation.api.api_methods[invocation.api_method_name]
- invocation.expects = info ? info[:expects] : nil
- invocation.returns = info ? info[:returns] : nil
- if invocation.expects
- i = 0
- invocation.method_ordered_params = request.method_params.map do |param|
- if invocation.protocol.is_a?(Protocol::XmlRpc::XmlRpcProtocol)
- marshaler = invocation.protocol.marshaler
- decoded_param = WS::Encoding::XmlRpcDecodedParam.new(param.info.name, param.value)
- marshaled_param = marshaler.typed_unmarshal(decoded_param, invocation.expects[i]) rescue nil
- param = marshaled_param ? marshaled_param : param
- end
- i += 1
- param.value
- end
- i = 0
- params = []
- invocation.expects.each do |spec|
- type_binding = invocation.protocol.register_signature_type(spec)
- info = WS::ParamInfo.create(spec, type_binding, i)
- params << WS::Param.new(invocation.method_ordered_params[i], info)
- i += 1
- end
- invocation.method_ws_params = params
- invocation.method_named_params = {}
- invocation.method_ws_params.each do |param|
- invocation.method_named_params[param.info.name] = param.value
- end
- else
- invocation.method_ordered_params = []
- invocation.method_named_params = {}
+ request.api_method = invocation.api_method
+ begin
+ invocation.method_ordered_params = invocation.api_method.cast_expects_ws2ruby(request.protocol.marshaler, request.method_params)
+ rescue
+ invocation.method_ordered_params = request.method_params.map{ |x| x.value }
end
- if invocation.returns
- invocation.returns.each do |spec|
- invocation.protocol.register_signature_type(spec)
- end
+ invocation.method_named_params = {}
+ invocation.api_method.param_names.inject(0) do |m, n|
+ invocation.method_named_params[n] = invocation.method_ordered_params[m]
+ m + 1
end
invocation
end
@@ -139,13 +113,9 @@ module ActionWebService # :nodoc:
attr_accessor :protocol
attr_accessor :service_name
attr_accessor :api
- attr_accessor :public_method_name
- attr_accessor :api_method_name
+ attr_accessor :api_method
attr_accessor :method_ordered_params
attr_accessor :method_named_params
- attr_accessor :method_ws_params
- attr_accessor :expects
- attr_accessor :returns
attr_accessor :service
end
end
diff --git a/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb b/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb
index 7080f813d4..5289b0b84d 100644
--- a/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb
+++ b/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb
@@ -76,7 +76,10 @@ module ActionWebService # :nodoc:
unless self.class.web_service_exception_reporting
exception = DispatcherError.new("Internal server error (exception raised)")
end
- response = request.protocol.marshal_response(request.method_name, exception, exception.class)
+ api_method = request.api_method ? request.api_method.dup : nil
+ api_method ||= request.api.dummy_api_method_instance(request.method_name)
+ api_method.instance_eval{ @returns = [ exception.class ] }
+ response = request.protocol.marshal_response(api_method, exception)
send_web_service_response(response)
else
if self.class.web_service_exception_reporting
@@ -95,7 +98,7 @@ module ActionWebService # :nodoc:
end
@session ||= {}
@assigns ||= {}
- @params['action'] = invocation.api_method_name.to_s
+ @params['action'] = invocation.api_method.name.to_s
if before_action == false
raise(DispatcherError, "Method filtered")
end
@@ -224,18 +227,18 @@ module ActionWebService # :nodoc:
# APIs
apis.each do |api_name, values|
api = values[0]
- api.api_methods.each do |name, info|
+ api.api_methods.each do |name, method|
gen = lambda do |msg_name, direction|
xm.message('name' => msg_name) do
sym = nil
if direction == :out
- returns = info[:returns]
+ returns = method.returns
if returns
binding = marshaler.register_type(returns[0])
xm.part('name' => 'return', 'type' => binding.qualified_type_name('typens'))
end
else
- expects = info[:expects]
+ expects = method.expects
i = 1
expects.each do |type|
if type.is_a?(Hash)
@@ -251,7 +254,7 @@ module ActionWebService # :nodoc:
end
end
end
- public_name = api.public_api_method_name(name)
+ public_name = method.public_name
gen.call(public_name, :in)
gen.call("#{public_name}Response", :out)
end
@@ -259,11 +262,10 @@ module ActionWebService # :nodoc:
# Port
port_name = port_name_for(global_service_name, api_name)
xm.portType('name' => port_name) do
- api.api_methods.each do |name, info|
- public_name = api.public_api_method_name(name)
- xm.operation('name' => public_name) do
- xm.input('message' => "typens:#{public_name}")
- xm.output('message' => "typens:#{public_name}Response")
+ api.api_methods.each do |name, method|
+ xm.operation('name' => method.public_name) do
+ xm.input('message' => "typens:#{method.public_name}")
+ xm.output('message' => "typens:#{method.public_name}Response")
end
end
end
@@ -272,16 +274,15 @@ module ActionWebService # :nodoc:
binding_name = binding_name_for(global_service_name, api_name)
xm.binding('name' => binding_name, 'type' => "typens:#{port_name}") do
xm.soap(:binding, 'style' => 'rpc', 'transport' => SoapHttpTransport)
- api.api_methods.each do |name, info|
- public_name = api.public_api_method_name(name)
- xm.operation('name' => public_name) do
+ api.api_methods.each do |name, method|
+ xm.operation('name' => method.public_name) do
case web_service_dispatching_mode
when :direct, :layered
- soap_action = soap_action_base + "/api/" + public_name
+ soap_action = soap_action_base + "/api/" + method.public_name
when :delegated
soap_action = soap_action_base \
+ "/" + api_name.to_s \
- + "/" + public_name
+ + "/" + method.public_name
end
xm.soap(:operation, 'soapAction' => soap_action)
xm.input do
@@ -337,8 +338,8 @@ module ActionWebService # :nodoc:
end
def traverse_custom_types(api, marshaler, &block)
- api.api_methods.each do |name, info|
- expects, returns = info[:expects], info[:returns]
+ api.api_methods.each do |name, method|
+ expects, returns = method.expects, method.returns
expects.each{|x| traverse_custom_type_spec(marshaler, x, &block)} if expects
returns.each{|x| traverse_custom_type_spec(marshaler, x, &block)} if returns
end