diff options
Diffstat (limited to 'actionwebservice/lib/action_web_service/vendor/ws/encoding')
3 files changed, 169 insertions, 0 deletions
diff --git a/actionwebservice/lib/action_web_service/vendor/ws/encoding/abstract.rb b/actionwebservice/lib/action_web_service/vendor/ws/encoding/abstract.rb new file mode 100644 index 0000000000..257c7d0993 --- /dev/null +++ b/actionwebservice/lib/action_web_service/vendor/ws/encoding/abstract.rb @@ -0,0 +1,26 @@ +module WS + module Encoding + # Encoders operate on _foreign_ objects. That is, Ruby object + # instances that are the _marshaling format specific_ representation + # of objects. In other words, objects that have not yet been marshaled, but + # are in protocol-specific form (such as an AST or DOM element), and not + # native Ruby form. + class AbstractEncoding + def encode_rpc_call(method_name, params) + raise NotImplementedError + end + + def decode_rpc_call(obj) + raise NotImplementedError + end + + def encode_rpc_response(method_name, return_value) + raise NotImplementedError + end + + def decode_rpc_response(obj) + raise NotImplementedError + end + end + end +end diff --git a/actionwebservice/lib/action_web_service/vendor/ws/encoding/soap_rpc_encoding.rb b/actionwebservice/lib/action_web_service/vendor/ws/encoding/soap_rpc_encoding.rb new file mode 100644 index 0000000000..f4d2f5a7d6 --- /dev/null +++ b/actionwebservice/lib/action_web_service/vendor/ws/encoding/soap_rpc_encoding.rb @@ -0,0 +1,90 @@ +require 'soap/processor' +require 'soap/mapping' +require 'soap/rpc/element' + +module WS + module Encoding + class SoapRpcError < WSError + end + + class SoapRpcEncoding < AbstractEncoding + attr_accessor :method_namespace + + def initialize(method_namespace='') + @method_namespace = method_namespace + end + + def encode_rpc_call(method_name, foreign_params) + qname = create_method_qname(method_name) + param_def = [] + params = foreign_params.map do |p| + param_def << ['in', p.param.info.name, p.param.info.data.mapping] + [p.param.info.name, p.soap_object] + end + request = SOAP::RPC::SOAPMethodRequest.new(qname, param_def) + request.set_param(params) + envelope = create_soap_envelope(request) + SOAP::Processor.marshal(envelope) + end + + def decode_rpc_call(obj) + envelope = SOAP::Processor.unmarshal(obj) + unless envelope + raise(SoapRpcError, "Malformed SOAP request") + end + request = envelope.body.request + method_name = request.elename.name + params = request.collect do |key, value| + info = ParamInfo.new(key, nil, nil) + param = Param.new(nil, info) + Marshaling::SoapForeignObject.new(param, request[key]) + end + [method_name, params] + end + + def encode_rpc_response(method_name, return_value) + response = nil + qname = create_method_qname(method_name) + if return_value.nil? + response = SOAP::RPC::SOAPMethodResponse.new(qname, nil) + else + param = return_value.param + soap_object = return_value.soap_object + param_def = [['retval', 'return', param.info.data.mapping]] + if soap_object.is_a?(SOAP::SOAPFault) + response = soap_object + else + response = SOAP::RPC::SOAPMethodResponse.new(qname, param_def) + response.retval = soap_object + end + end + envelope = create_soap_envelope(response) + SOAP::Processor.marshal(envelope) + end + + def decode_rpc_response(obj) + envelope = SOAP::Processor.unmarshal(obj) + unless envelope + raise(SoapRpcError, "Malformed SOAP response") + end + method_name = envelope.body.request.elename.name + return_value = envelope.body.response + info = ParamInfo.new('return', nil, nil) + param = Param.new(nil, info) + return_value = Marshaling::SoapForeignObject.new(param, return_value) + [method_name, return_value] + end + + private + def create_soap_envelope(body) + header = SOAP::SOAPHeader.new + body = SOAP::SOAPBody.new(body) + SOAP::SOAPEnvelope.new(header, body) + end + + def create_method_qname(method_name) + XSD::QName.new(@method_namespace, method_name) + end + end + end +end diff --git a/actionwebservice/lib/action_web_service/vendor/ws/encoding/xmlrpc_encoding.rb b/actionwebservice/lib/action_web_service/vendor/ws/encoding/xmlrpc_encoding.rb new file mode 100644 index 0000000000..b38ae81abf --- /dev/null +++ b/actionwebservice/lib/action_web_service/vendor/ws/encoding/xmlrpc_encoding.rb @@ -0,0 +1,53 @@ +require 'xmlrpc/marshal' + +module WS + module Encoding + class XmlRpcError < WSError + end + + class XmlRpcEncoding < AbstractEncoding + def encode_rpc_call(method_name, params) + XMLRPC::Marshal.dump_call(method_name, *params) + end + + def decode_rpc_call(obj) + method_name, params = XMLRPC::Marshal.load_call(obj) rescue nil + unless method_name && params + raise(XmlRpcError, "Malformed XML-RPC request") + end + i = 0 + params = params.map do |value| + param = XmlRpcDecodedParam.new("param#{i}", value) + i += 1 + param + end + [method_name, params] + end + + def encode_rpc_response(method_name, return_value) + if return_value.nil? + XMLRPC::Marshal.dump_response(true) + else + XMLRPC::Marshal.dump_response(return_value) + end + end + + def decode_rpc_response(obj) + return_value = XMLRPC::Marshal.load_response(obj) rescue nil + if return_value.nil? + raise(XmlRpcError, "Malformed XML-RPC response") + end + [nil, XmlRpcDecodedParam.new('return', return_value)] + end + end + + class XmlRpcDecodedParam + attr :param + + def initialize(name, value) + info = ParamInfo.new(name, value.class) + @param = Param.new(value, info) + end + end + end +end |