aboutsummaryrefslogtreecommitdiffstats
path: root/actionwebservice/lib/action_web_service/vendor/ws/encoding/soap_rpc_encoding.rb
blob: f4d2f5a7d606d77babe4396ce1d7c2ee36a1a113 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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