aboutsummaryrefslogtreecommitdiffstats
path: root/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb')
-rw-r--r--actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb184
1 files changed, 32 insertions, 152 deletions
diff --git a/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb b/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb
index 1addccba56..1533a2bdb9 100644
--- a/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb
+++ b/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb
@@ -1,167 +1,47 @@
-require 'xmlrpc/parser'
-require 'xmlrpc/create'
-require 'xmlrpc/config'
-require 'xmlrpc/utils'
-require 'singleton'
-
-module XMLRPC # :nodoc:
- class XmlRpcHelper # :nodoc:
- include Singleton
- include ParserWriterChooseMixin
-
- def parse_method_call(message)
- parser().parseMethodCall(message)
- end
-
- def create_method_response(successful, return_value)
- create().methodResponse(successful, return_value)
- end
- end
-end
-
-module ActionWebService # :nodoc:
- module Protocol # :nodoc:
- module XmlRpc # :nodoc:
- def self.append_features(base) # :nodoc:
- super
- base.register_protocol(BodyOnly, XmlRpcProtocol)
+module ActionWebService
+ module Protocol
+ module XmlRpc
+ def self.included(base)
+ base.register_protocol(XmlRpcProtocol)
end
+
+ class XmlRpcProtocol
+ attr :marshaler
- class XmlRpcProtocol < AbstractProtocol # :nodoc:
- def self.create_protocol_request(container_class, action_pack_request)
- helper = XMLRPC::XmlRpcHelper.instance
- service_name = action_pack_request.parameters['action']
- methodname, params = helper.parse_method_call(action_pack_request.raw_post)
- methodname.gsub!(/^[^\.]+\./, '') unless methodname =~ /^system\./ # XXX
- protocol = XmlRpcProtocol.new(container_class)
- content_type = action_pack_request.env['HTTP_CONTENT_TYPE']
- content_type ||= 'text/xml'
- request = ProtocolRequest.new(protocol,
- action_pack_request.raw_post,
- service_name.to_sym,
- methodname,
- content_type,
- :xmlrpc_values => params)
- request
- rescue
- nil
- end
-
- def self.create_protocol_client(api, protocol_name, endpoint_uri, options)
- return nil unless protocol_name.to_s.downcase.to_sym == :xmlrpc
- ActionWebService::Client::XmlRpc.new(api, endpoint_uri, options)
+ def initialize
+ @encoder = WS::Encoding::XmlRpcEncoding.new
+ @marshaler = WS::Marshaling::XmlRpcMarshaler.new
end
- def initialize(container_class)
- super(container_class)
+ def unmarshal_request(ap_request)
+ method_name, params = @encoder.decode_rpc_call(ap_request.raw_post)
+ params = params.map{|x| @marshaler.unmarshal(x)}
+ service_name = ap_request.parameters['action']
+ Request.new(self, method_name, params, service_name)
+ rescue
+ nil
end
- def unmarshal_request(protocol_request)
- values = protocol_request.options[:xmlrpc_values]
- signature = protocol_request.signature
- if signature
- values = self.class.transform_incoming_method_params(self.class.transform_array_types(signature), values)
- protocol_request.check_parameter_types(values, check_array_types(signature))
- values
- else
- protocol_request.checked? ? [] : values
- end
- end
-
- def marshal_response(protocol_request, return_value)
- helper = XMLRPC::XmlRpcHelper.instance
- signature = protocol_request.return_signature
- if signature
- protocol_request.check_parameter_types([return_value], check_array_types(signature))
- return_value = self.class.transform_return_value(self.class.transform_array_types(signature), return_value)
- raw_response = helper.create_method_response(true, return_value)
+ def marshal_response(method_name, return_value, signature_type)
+ if !return_value.nil? && signature_type
+ type_binding = @marshaler.register_type(signature_type)
+ info = WS::ParamInfo.create(signature_type, 0, type_binding)
+ return_value = @marshaler.marshal(WS::Param.new(return_value, info))
else
- # XML-RPC doesn't have the concept of a void method, nor does it
- # support a nil return value, so return true if we would have returned
- # nil
- if protocol_request.checked?
- raw_response = helper.create_method_response(true, true)
- else
- return_value = true if return_value.nil?
- raw_response = helper.create_method_response(true, return_value)
- end
+ return_value = nil
end
- ProtocolResponse.new(self, raw_response, 'text/xml')
+ body = @encoder.encode_rpc_response(method_name, return_value)
+ Response.new(body, 'text/xml')
end
-
- def marshal_exception(exception)
- helper = XMLRPC::XmlRpcHelper.instance
- exception = XMLRPC::FaultException.new(1, exception.message)
- raw_response = helper.create_method_response(false, exception)
- ProtocolResponse.new(self, raw_response, 'text/xml')
- end
-
- class << self
- def transform_incoming_method_params(signature, params)
- (1..signature.size).each do |i|
- i -= 1
- params[i] = xmlrpc_to_ruby(params[i], signature[i])
- end
- params
- end
-
- def transform_return_value(signature, return_value)
- ruby_to_xmlrpc(return_value, signature[0])
- end
-
- def ruby_to_xmlrpc(param, param_class)
- if param_class.is_a?(XmlRpcArray)
- param.map{|p| ruby_to_xmlrpc(p, param_class.klass)}
- elsif param_class.ancestors.include?(ActiveRecord::Base)
- param.instance_variable_get('@attributes')
- elsif param_class.ancestors.include?(ActionWebService::Struct)
- struct = {}
- param_class.members.each do |name, klass|
- value = param.send(name)
- next if value.nil?
- struct[name.to_s] = value
- end
- struct
- else
- param
- end
- end
- def xmlrpc_to_ruby(param, param_class)
- if param_class.is_a?(XmlRpcArray)
- param.map{|p| xmlrpc_to_ruby(p, param_class.klass)}
- elsif param_class.ancestors.include?(ActiveRecord::Base)
- raise(ProtocolError, "incoming ActiveRecord::Base types are not allowed")
- elsif param_class.ancestors.include?(ActionWebService::Struct)
- unless param.is_a?(Hash)
- raise(ProtocolError, "expected parameter to be a Hash")
- end
- new_param = param_class.new
- param_class.members.each do |name, klass|
- new_param.send('%s=' % name.to_s, param[name.to_s])
- end
- new_param
- else
- param
- end
- end
+ def register_signature_type(spec)
+ nil
+ end
- def transform_array_types(signature)
- signature.map{|x| x.is_a?(Array) ? XmlRpcArray.new(x[0]) : x}
- end
+ def protocol_client(api, protocol_name, endpoint_uri, options)
+ return nil unless protocol_name == :xmlrpc
+ ActionWebService::Client::XmlRpc.new(api, endpoint_uri, options)
end
-
- private
- def check_array_types(signature)
- signature.map{|x| x.is_a?(Array) ? Array : x}
- end
-
- class XmlRpcArray
- attr :klass
- def initialize(klass)
- @klass = klass
- end
- end
end
end
end