98 lines
3.2 KiB
Ruby
98 lines
3.2 KiB
Ruby
require 'xmlrpc/marshal'
|
|
require 'action_web_service/client/xmlrpc_client'
|
|
|
|
module XMLRPC # :nodoc:
|
|
class FaultException # :nodoc:
|
|
alias :message :faultString
|
|
end
|
|
end
|
|
|
|
module ActionWebService # :nodoc:
|
|
module API # :nodoc:
|
|
class Base # :nodoc:
|
|
def self.xmlrpc_client(endpoint_uri, options={})
|
|
ActionWebService::Client::XmlRpc.new self, endpoint_uri, options
|
|
end
|
|
end
|
|
end
|
|
|
|
module Protocol # :nodoc:
|
|
module XmlRpc # :nodoc:
|
|
def self.included(base)
|
|
base.register_protocol(XmlRpcProtocol)
|
|
end
|
|
|
|
class XmlRpcProtocol < AbstractProtocol # :nodoc:
|
|
def self.create(controller)
|
|
XmlRpcProtocol.new
|
|
end
|
|
|
|
def decode_action_pack_request(action_pack_request)
|
|
service_name = action_pack_request.parameters['action']
|
|
decode_request(action_pack_request.raw_post, service_name)
|
|
end
|
|
|
|
def decode_request(raw_request, service_name)
|
|
method_name, params = XMLRPC::Marshal.load_call(raw_request)
|
|
Request.new(self, method_name, params, service_name)
|
|
end
|
|
|
|
def encode_request(method_name, params, param_types)
|
|
if param_types
|
|
params = params.dup
|
|
param_types.each_with_index{ |type, i| params[i] = value_to_xmlrpc_wire_format(params[i], type) }
|
|
end
|
|
XMLRPC::Marshal.dump_call(method_name, *params)
|
|
end
|
|
|
|
def decode_response(raw_response)
|
|
[nil, XMLRPC::Marshal.load_response(raw_response)]
|
|
end
|
|
|
|
def encode_response(method_name, return_value, return_type, protocol_options={})
|
|
if return_value && return_type
|
|
return_value = value_to_xmlrpc_wire_format(return_value, return_type)
|
|
end
|
|
return_value = false if return_value.nil?
|
|
raw_response = XMLRPC::Marshal.dump_response(return_value)
|
|
Response.new(raw_response, 'text/xml', return_value)
|
|
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
|
|
|
|
def value_to_xmlrpc_wire_format(value, value_type)
|
|
if value_type.array?
|
|
value.map{ |val| value_to_xmlrpc_wire_format(val, value_type.element_type) }
|
|
else
|
|
if value.is_a?(ActionWebService::Struct)
|
|
struct = {}
|
|
value.class.members.each do |name, type|
|
|
member_value = value[name]
|
|
next if member_value.nil?
|
|
struct[name.to_s] = value_to_xmlrpc_wire_format(member_value, type)
|
|
end
|
|
struct
|
|
elsif value.is_a?(ActiveRecord::Base)
|
|
struct = {}
|
|
value.attributes.each do |key, member_value|
|
|
next if member_value.nil?
|
|
struct[key.to_s] = member_value
|
|
end
|
|
struct
|
|
elsif value.is_a?(ActionWebService::Base64)
|
|
XMLRPC::Base64.new(value)
|
|
elsif value.is_a?(Exception) && !value.is_a?(XMLRPC::FaultException)
|
|
XMLRPC::FaultException.new(2, value.message)
|
|
else
|
|
value
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|