actionwebservice 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/{ChangeLog → CHANGELOG} +20 -0
- data/README +45 -1
- data/Rakefile +12 -10
- data/TODO +8 -9
- data/lib/action_web_service.rb +10 -6
- data/lib/action_web_service/api.rb +1 -2
- data/lib/action_web_service/api/{abstract.rb → base.rb} +14 -71
- data/lib/action_web_service/base.rb +0 -3
- data/lib/action_web_service/client/base.rb +1 -12
- data/lib/action_web_service/client/soap_client.rb +49 -17
- data/lib/action_web_service/client/xmlrpc_client.rb +20 -15
- data/lib/action_web_service/container.rb +3 -85
- data/lib/action_web_service/{api/action_controller.rb → container/action_controller_container.rb} +2 -2
- data/lib/action_web_service/container/delegated_container.rb +87 -0
- data/lib/action_web_service/container/direct_container.rb +70 -0
- data/lib/action_web_service/dispatcher/abstract.rb +100 -102
- data/lib/action_web_service/dispatcher/action_controller_dispatcher.rb +199 -137
- data/lib/action_web_service/protocol.rb +1 -1
- data/lib/action_web_service/protocol/abstract.rb +14 -112
- data/lib/action_web_service/protocol/discovery.rb +37 -0
- data/lib/action_web_service/protocol/soap_protocol.rb +32 -458
- data/lib/action_web_service/protocol/xmlrpc_protocol.rb +29 -149
- data/lib/action_web_service/struct.rb +2 -5
- data/lib/action_web_service/test_invoke.rb +130 -0
- data/lib/action_web_service/vendor/ws.rb +4 -0
- data/lib/action_web_service/vendor/ws/common.rb +8 -0
- data/lib/action_web_service/vendor/ws/encoding.rb +3 -0
- data/lib/action_web_service/vendor/ws/encoding/abstract.rb +26 -0
- data/lib/action_web_service/vendor/ws/encoding/soap_rpc_encoding.rb +90 -0
- data/lib/action_web_service/vendor/ws/encoding/xmlrpc_encoding.rb +53 -0
- data/lib/action_web_service/vendor/ws/marshaling.rb +3 -0
- data/lib/action_web_service/vendor/ws/marshaling/abstract.rb +17 -0
- data/lib/action_web_service/vendor/ws/marshaling/soap_marshaling.rb +277 -0
- data/lib/action_web_service/vendor/ws/marshaling/xmlrpc_marshaling.rb +116 -0
- data/lib/action_web_service/vendor/ws/types.rb +162 -0
- data/test/abstract_client.rb +8 -11
- data/test/abstract_dispatcher.rb +370 -0
- data/test/abstract_unit.rb +1 -0
- data/test/api_test.rb +18 -1
- data/test/apis/auto_load_api.rb +3 -0
- data/test/apis/broken_auto_load_api.rb +2 -0
- data/test/client_soap_test.rb +16 -3
- data/test/client_xmlrpc_test.rb +16 -4
- data/test/container_test.rb +28 -8
- data/test/dispatcher_action_controller_soap_test.rb +106 -0
- data/test/dispatcher_action_controller_xmlrpc_test.rb +44 -0
- data/test/gencov +1 -1
- data/test/invocation_test.rb +39 -3
- data/test/run +4 -4
- data/test/test_invoke_test.rb +77 -0
- data/test/ws/abstract_encoding.rb +68 -0
- data/test/ws/abstract_unit.rb +13 -0
- data/test/ws/gencov +3 -0
- data/test/ws/run +5 -0
- data/test/ws/soap_marshaling_test.rb +91 -0
- data/test/ws/soap_rpc_encoding_test.rb +47 -0
- data/test/ws/types_test.rb +41 -0
- data/test/ws/xmlrpc_encoding_test.rb +34 -0
- metadata +48 -19
- data/lib/action_web_service/protocol/registry.rb +0 -55
- data/lib/action_web_service/support/signature.rb +0 -100
- data/test/abstract_soap.rb +0 -58
- data/test/dispatcher_action_controller_test.rb +0 -186
- data/test/protocol_registry_test.rb +0 -53
- data/test/protocol_soap_test.rb +0 -252
- data/test/protocol_xmlrpc_test.rb +0 -147
@@ -1,167 +1,47 @@
|
|
1
|
-
require 'xmlrpc/parser'
|
2
|
-
require 'xmlrpc/create'
|
3
|
-
require 'xmlrpc/config'
|
4
|
-
require 'xmlrpc/utils'
|
5
|
-
require 'singleton'
|
6
|
-
|
7
|
-
module XMLRPC # :nodoc:
|
8
|
-
class XmlRpcHelper # :nodoc:
|
9
|
-
include Singleton
|
10
|
-
include ParserWriterChooseMixin
|
11
|
-
|
12
|
-
def parse_method_call(message)
|
13
|
-
parser().parseMethodCall(message)
|
14
|
-
end
|
15
|
-
|
16
|
-
def create_method_response(successful, return_value)
|
17
|
-
create().methodResponse(successful, return_value)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
1
|
module ActionWebService # :nodoc:
|
23
2
|
module Protocol # :nodoc:
|
24
3
|
module XmlRpc # :nodoc:
|
25
|
-
def self.
|
26
|
-
|
27
|
-
base.register_protocol(BodyOnly, XmlRpcProtocol)
|
4
|
+
def self.included(base)
|
5
|
+
base.register_protocol(XmlRpcProtocol)
|
28
6
|
end
|
7
|
+
|
8
|
+
class XmlRpcProtocol # :nodoc:
|
9
|
+
attr :marshaler
|
29
10
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
service_name = action_pack_request.parameters['action']
|
34
|
-
methodname, params = helper.parse_method_call(action_pack_request.raw_post)
|
35
|
-
methodname.gsub!(/^[^\.]+\./, '') unless methodname =~ /^system\./ # XXX
|
36
|
-
protocol = XmlRpcProtocol.new(container_class)
|
37
|
-
content_type = action_pack_request.env['HTTP_CONTENT_TYPE']
|
38
|
-
content_type ||= 'text/xml'
|
39
|
-
request = ProtocolRequest.new(protocol,
|
40
|
-
action_pack_request.raw_post,
|
41
|
-
service_name.to_sym,
|
42
|
-
methodname,
|
43
|
-
content_type,
|
44
|
-
:xmlrpc_values => params)
|
45
|
-
request
|
46
|
-
rescue
|
47
|
-
nil
|
48
|
-
end
|
49
|
-
|
50
|
-
def self.create_protocol_client(api, protocol_name, endpoint_uri, options)
|
51
|
-
return nil unless protocol_name.to_s.downcase.to_sym == :xmlrpc
|
52
|
-
ActionWebService::Client::XmlRpc.new(api, endpoint_uri, options)
|
11
|
+
def initialize
|
12
|
+
@encoder = WS::Encoding::XmlRpcEncoding.new
|
13
|
+
@marshaler = WS::Marshaling::XmlRpcMarshaler.new
|
53
14
|
end
|
54
15
|
|
55
|
-
def
|
56
|
-
|
16
|
+
def unmarshal_request(ap_request)
|
17
|
+
method_name, params = @encoder.decode_rpc_call(ap_request.raw_post)
|
18
|
+
params = params.map{|x| @marshaler.unmarshal(x)}
|
19
|
+
service_name = ap_request.parameters['action']
|
20
|
+
Request.new(self, method_name, params, service_name)
|
21
|
+
rescue
|
22
|
+
nil
|
57
23
|
end
|
58
24
|
|
59
|
-
def
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
protocol_request.check_parameter_types(values, check_array_types(signature))
|
65
|
-
values
|
66
|
-
else
|
67
|
-
protocol_request.checked? ? [] : values
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def marshal_response(protocol_request, return_value)
|
72
|
-
helper = XMLRPC::XmlRpcHelper.instance
|
73
|
-
signature = protocol_request.return_signature
|
74
|
-
if signature
|
75
|
-
protocol_request.check_parameter_types([return_value], check_array_types(signature))
|
76
|
-
return_value = self.class.transform_return_value(self.class.transform_array_types(signature), return_value)
|
77
|
-
raw_response = helper.create_method_response(true, return_value)
|
25
|
+
def marshal_response(method_name, return_value, signature_type)
|
26
|
+
if !return_value.nil? && signature_type
|
27
|
+
type_binding = @marshaler.register_type(signature_type)
|
28
|
+
info = WS::ParamInfo.create(signature_type, type_binding, 0)
|
29
|
+
return_value = @marshaler.marshal(WS::Param.new(return_value, info))
|
78
30
|
else
|
79
|
-
|
80
|
-
# support a nil return value, so return true if we would have returned
|
81
|
-
# nil
|
82
|
-
if protocol_request.checked?
|
83
|
-
raw_response = helper.create_method_response(true, true)
|
84
|
-
else
|
85
|
-
return_value = true if return_value.nil?
|
86
|
-
raw_response = helper.create_method_response(true, return_value)
|
87
|
-
end
|
31
|
+
return_value = nil
|
88
32
|
end
|
89
|
-
|
33
|
+
body = @encoder.encode_rpc_response(method_name, return_value)
|
34
|
+
Response.new(body, 'text/xml')
|
90
35
|
end
|
91
|
-
|
92
|
-
def marshal_exception(exception)
|
93
|
-
helper = XMLRPC::XmlRpcHelper.instance
|
94
|
-
exception = XMLRPC::FaultException.new(1, exception.message)
|
95
|
-
raw_response = helper.create_method_response(false, exception)
|
96
|
-
ProtocolResponse.new(self, raw_response, 'text/xml')
|
97
|
-
end
|
98
|
-
|
99
|
-
class << self
|
100
|
-
def transform_incoming_method_params(signature, params)
|
101
|
-
(1..signature.size).each do |i|
|
102
|
-
i -= 1
|
103
|
-
params[i] = xmlrpc_to_ruby(params[i], signature[i])
|
104
|
-
end
|
105
|
-
params
|
106
|
-
end
|
107
|
-
|
108
|
-
def transform_return_value(signature, return_value)
|
109
|
-
ruby_to_xmlrpc(return_value, signature[0])
|
110
|
-
end
|
111
|
-
|
112
|
-
def ruby_to_xmlrpc(param, param_class)
|
113
|
-
if param_class.is_a?(XmlRpcArray)
|
114
|
-
param.map{|p| ruby_to_xmlrpc(p, param_class.klass)}
|
115
|
-
elsif param_class.ancestors.include?(ActiveRecord::Base)
|
116
|
-
param.instance_variable_get('@attributes')
|
117
|
-
elsif param_class.ancestors.include?(ActionWebService::Struct)
|
118
|
-
struct = {}
|
119
|
-
param_class.members.each do |name, klass|
|
120
|
-
value = param.send(name)
|
121
|
-
next if value.nil?
|
122
|
-
struct[name.to_s] = value
|
123
|
-
end
|
124
|
-
struct
|
125
|
-
else
|
126
|
-
param
|
127
|
-
end
|
128
|
-
end
|
129
36
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
elsif param_class.ancestors.include?(ActiveRecord::Base)
|
134
|
-
raise(ProtocolError, "incoming ActiveRecord::Base types are not allowed")
|
135
|
-
elsif param_class.ancestors.include?(ActionWebService::Struct)
|
136
|
-
unless param.is_a?(Hash)
|
137
|
-
raise(ProtocolError, "expected parameter to be a Hash")
|
138
|
-
end
|
139
|
-
new_param = param_class.new
|
140
|
-
param_class.members.each do |name, klass|
|
141
|
-
new_param.send('%s=' % name.to_s, param[name.to_s])
|
142
|
-
end
|
143
|
-
new_param
|
144
|
-
else
|
145
|
-
param
|
146
|
-
end
|
147
|
-
end
|
37
|
+
def register_signature_type(spec)
|
38
|
+
nil
|
39
|
+
end
|
148
40
|
|
149
|
-
|
150
|
-
|
151
|
-
|
41
|
+
def protocol_client(api, protocol_name, endpoint_uri, options)
|
42
|
+
return nil unless protocol_name == :xmlrpc
|
43
|
+
ActionWebService::Client::XmlRpc.new(api, endpoint_uri, options)
|
152
44
|
end
|
153
|
-
|
154
|
-
private
|
155
|
-
def check_array_types(signature)
|
156
|
-
signature.map{|x| x.is_a?(Array) ? Array : x}
|
157
|
-
end
|
158
|
-
|
159
|
-
class XmlRpcArray
|
160
|
-
attr :klass
|
161
|
-
def initialize(klass)
|
162
|
-
@klass = klass
|
163
|
-
end
|
164
|
-
end
|
165
45
|
end
|
166
46
|
end
|
167
47
|
end
|
@@ -17,8 +17,7 @@ module ActionWebService
|
|
17
17
|
# person = Person.new(:id => 5, :firstname => 'john', :lastname => 'doe')
|
18
18
|
#
|
19
19
|
# Active Record model classes are already implicitly supported for method
|
20
|
-
# return signatures.
|
21
|
-
# automatically generated if its present in a signature.
|
20
|
+
# return signatures.
|
22
21
|
class Struct
|
23
22
|
|
24
23
|
# If a Hash is given as argument to an ActionWebService::Struct constructor,
|
@@ -35,12 +34,10 @@ module ActionWebService
|
|
35
34
|
end
|
36
35
|
|
37
36
|
class << self
|
38
|
-
include ActionWebService::Signature
|
39
|
-
|
40
37
|
# Creates a structure member with the specified +name+ and +type+. Generates
|
41
38
|
# accessor methods for reading and writing the member value.
|
42
39
|
def member(name, type)
|
43
|
-
write_inheritable_hash("struct_members", name =>
|
40
|
+
write_inheritable_hash("struct_members", name => WS::BaseTypes.canonical_param_type_class(type))
|
44
41
|
class_eval <<-END
|
45
42
|
def #{name}; @#{name}; end
|
46
43
|
def #{name}=(value); @#{name} = value; end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
module Test
|
4
|
+
module Unit
|
5
|
+
class TestCase # :nodoc:
|
6
|
+
private
|
7
|
+
# invoke the specified API method
|
8
|
+
def invoke_direct(method_name, *args)
|
9
|
+
prepare_request('api', 'api', method_name, *args)
|
10
|
+
@controller.process(@request, @response)
|
11
|
+
decode_rpc_response
|
12
|
+
end
|
13
|
+
alias_method :invoke, :invoke_direct
|
14
|
+
|
15
|
+
# invoke the specified API method on the specified service
|
16
|
+
def invoke_delegated(service_name, method_name, *args)
|
17
|
+
prepare_request(service_name.to_s, service_name, method_name, *args)
|
18
|
+
@controller.process(@request, @response)
|
19
|
+
decode_rpc_response
|
20
|
+
end
|
21
|
+
|
22
|
+
# invoke the specified layered API method on the correct service
|
23
|
+
def invoke_layered(service_name, method_name, *args)
|
24
|
+
if protocol == :soap
|
25
|
+
raise "SOAP protocol support for :layered dispatching mode is not available"
|
26
|
+
end
|
27
|
+
prepare_request('api', service_name, method_name, *args)
|
28
|
+
@controller.process(@request, @response)
|
29
|
+
decode_rpc_response
|
30
|
+
end
|
31
|
+
|
32
|
+
# ---------------------- internal ---------------------------
|
33
|
+
|
34
|
+
def prepare_request(action, service_name, api_method_name, *args)
|
35
|
+
@request.request_parameters['action'] = action
|
36
|
+
@request.env['REQUEST_METHOD'] = 'POST'
|
37
|
+
@request.env['HTTP_CONTENT_TYPE'] = 'text/xml'
|
38
|
+
@request.env['RAW_POST_DATA'] = encode_rpc_call(service_name, api_method_name, *args)
|
39
|
+
case protocol
|
40
|
+
when :soap
|
41
|
+
soap_action = "/#{@controller.controller_name}/#{service_name}/#{public_method_name(service_name, api_method_name)}"
|
42
|
+
@request.env['HTTP_SOAPACTION'] = soap_action
|
43
|
+
when :xmlrpc
|
44
|
+
@request.env.delete('HTTP_SOAPACTION')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def encode_rpc_call(service_name, api_method_name, *args)
|
49
|
+
case @controller.web_service_dispatching_mode
|
50
|
+
when :direct
|
51
|
+
api = @controller.class.web_service_api
|
52
|
+
when :delegated, :layered
|
53
|
+
api = @controller.web_service_object(service_name.to_sym).class.web_service_api
|
54
|
+
end
|
55
|
+
info = api.api_methods[api_method_name.to_sym]
|
56
|
+
((info[:expects] || []) + (info[:returns] || [])).each do |spec|
|
57
|
+
marshaler.register_type spec
|
58
|
+
end
|
59
|
+
expects = info[:expects]
|
60
|
+
args = args.dup
|
61
|
+
(0..(args.length-1)).each do |i|
|
62
|
+
type_binding = marshaler.register_type(expects ? expects[i] : args[i].class)
|
63
|
+
info = WS::ParamInfo.create(expects ? expects[i] : args[i].class, type_binding, i)
|
64
|
+
args[i] = marshaler.marshal(WS::Param.new(args[i], info))
|
65
|
+
end
|
66
|
+
encoder.encode_rpc_call(public_method_name(service_name, api_method_name), args)
|
67
|
+
end
|
68
|
+
|
69
|
+
def decode_rpc_response
|
70
|
+
public_method_name, return_value = encoder.decode_rpc_response(@response.body)
|
71
|
+
result = marshaler.unmarshal(return_value).value
|
72
|
+
unless @return_exceptions
|
73
|
+
exception = is_exception?(result)
|
74
|
+
raise exception if exception
|
75
|
+
end
|
76
|
+
result
|
77
|
+
end
|
78
|
+
|
79
|
+
def public_method_name(service_name, api_method_name)
|
80
|
+
public_name = service_api(service_name).public_api_method_name(api_method_name)
|
81
|
+
if @controller.web_service_dispatching_mode == :layered
|
82
|
+
'%s.%s' % [service_name.to_s, public_name]
|
83
|
+
else
|
84
|
+
public_name
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def service_api(service_name)
|
89
|
+
case @controller.web_service_dispatching_mode
|
90
|
+
when :direct
|
91
|
+
@controller.class.web_service_api
|
92
|
+
when :delegated, :layered
|
93
|
+
@controller.web_service_object(service_name.to_sym).class.web_service_api
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def protocol
|
98
|
+
@protocol ||= :soap
|
99
|
+
end
|
100
|
+
|
101
|
+
def marshaler
|
102
|
+
case protocol
|
103
|
+
when :soap
|
104
|
+
@soap_marshaler ||= WS::Marshaling::SoapMarshaler.new 'urn:ActionWebService'
|
105
|
+
when :xmlrpc
|
106
|
+
@xmlrpc_marshaler ||= WS::Marshaling::XmlRpcMarshaler.new
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def encoder
|
111
|
+
case protocol
|
112
|
+
when :soap
|
113
|
+
@soap_encoder ||= WS::Encoding::SoapRpcEncoding.new 'urn:ActionWebService'
|
114
|
+
when :xmlrpc
|
115
|
+
@xmlrpc_encoder ||= WS::Encoding::XmlRpcEncoding.new
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def is_exception?(obj)
|
120
|
+
case protocol
|
121
|
+
when :soap
|
122
|
+
(obj.respond_to?(:detail) && obj.detail.respond_to?(:cause) && \
|
123
|
+
obj.detail.cause.is_a?(Exception)) ? obj.detail.cause : nil
|
124
|
+
when :xmlrpc
|
125
|
+
obj.is_a?(XMLRPC::FaultException) ? obj : nil
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module WS
|
2
|
+
module Encoding
|
3
|
+
# Encoders operate on _foreign_ objects. That is, Ruby object
|
4
|
+
# instances that are the _marshaling format specific_ representation
|
5
|
+
# of objects. In other words, objects that have not yet been marshaled, but
|
6
|
+
# are in protocol-specific form (such as an AST or DOM element), and not
|
7
|
+
# native Ruby form.
|
8
|
+
class AbstractEncoding
|
9
|
+
def encode_rpc_call(method_name, params)
|
10
|
+
raise NotImplementedError
|
11
|
+
end
|
12
|
+
|
13
|
+
def decode_rpc_call(obj)
|
14
|
+
raise NotImplementedError
|
15
|
+
end
|
16
|
+
|
17
|
+
def encode_rpc_response(method_name, return_value)
|
18
|
+
raise NotImplementedError
|
19
|
+
end
|
20
|
+
|
21
|
+
def decode_rpc_response(obj)
|
22
|
+
raise NotImplementedError
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'soap/processor'
|
2
|
+
require 'soap/mapping'
|
3
|
+
require 'soap/rpc/element'
|
4
|
+
|
5
|
+
module WS
|
6
|
+
module Encoding
|
7
|
+
class SoapRpcError < WSError
|
8
|
+
end
|
9
|
+
|
10
|
+
class SoapRpcEncoding < AbstractEncoding
|
11
|
+
attr_accessor :method_namespace
|
12
|
+
|
13
|
+
def initialize(method_namespace='')
|
14
|
+
@method_namespace = method_namespace
|
15
|
+
end
|
16
|
+
|
17
|
+
def encode_rpc_call(method_name, foreign_params)
|
18
|
+
qname = create_method_qname(method_name)
|
19
|
+
param_def = []
|
20
|
+
params = foreign_params.map do |p|
|
21
|
+
param_def << ['in', p.param.info.name, p.param.info.data.mapping]
|
22
|
+
[p.param.info.name, p.soap_object]
|
23
|
+
end
|
24
|
+
request = SOAP::RPC::SOAPMethodRequest.new(qname, param_def)
|
25
|
+
request.set_param(params)
|
26
|
+
envelope = create_soap_envelope(request)
|
27
|
+
SOAP::Processor.marshal(envelope)
|
28
|
+
end
|
29
|
+
|
30
|
+
def decode_rpc_call(obj)
|
31
|
+
envelope = SOAP::Processor.unmarshal(obj)
|
32
|
+
unless envelope
|
33
|
+
raise(SoapRpcError, "Malformed SOAP request")
|
34
|
+
end
|
35
|
+
request = envelope.body.request
|
36
|
+
method_name = request.elename.name
|
37
|
+
params = request.collect do |key, value|
|
38
|
+
info = ParamInfo.new(key, nil, nil)
|
39
|
+
param = Param.new(nil, info)
|
40
|
+
Marshaling::SoapForeignObject.new(param, request[key])
|
41
|
+
end
|
42
|
+
[method_name, params]
|
43
|
+
end
|
44
|
+
|
45
|
+
def encode_rpc_response(method_name, return_value)
|
46
|
+
response = nil
|
47
|
+
qname = create_method_qname(method_name)
|
48
|
+
if return_value.nil?
|
49
|
+
response = SOAP::RPC::SOAPMethodResponse.new(qname, nil)
|
50
|
+
else
|
51
|
+
param = return_value.param
|
52
|
+
soap_object = return_value.soap_object
|
53
|
+
param_def = [['retval', 'return', param.info.data.mapping]]
|
54
|
+
if soap_object.is_a?(SOAP::SOAPFault)
|
55
|
+
response = soap_object
|
56
|
+
else
|
57
|
+
response = SOAP::RPC::SOAPMethodResponse.new(qname, param_def)
|
58
|
+
response.retval = soap_object
|
59
|
+
end
|
60
|
+
end
|
61
|
+
envelope = create_soap_envelope(response)
|
62
|
+
SOAP::Processor.marshal(envelope)
|
63
|
+
end
|
64
|
+
|
65
|
+
def decode_rpc_response(obj)
|
66
|
+
envelope = SOAP::Processor.unmarshal(obj)
|
67
|
+
unless envelope
|
68
|
+
raise(SoapRpcError, "Malformed SOAP response")
|
69
|
+
end
|
70
|
+
method_name = envelope.body.request.elename.name
|
71
|
+
return_value = envelope.body.response
|
72
|
+
info = ParamInfo.new('return', nil, nil)
|
73
|
+
param = Param.new(nil, info)
|
74
|
+
return_value = Marshaling::SoapForeignObject.new(param, return_value)
|
75
|
+
[method_name, return_value]
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
def create_soap_envelope(body)
|
80
|
+
header = SOAP::SOAPHeader.new
|
81
|
+
body = SOAP::SOAPBody.new(body)
|
82
|
+
SOAP::SOAPEnvelope.new(header, body)
|
83
|
+
end
|
84
|
+
|
85
|
+
def create_method_qname(method_name)
|
86
|
+
XSD::QName.new(@method_namespace, method_name)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|