actionwebservice 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. data/CHANGELOG +21 -0
  2. data/README +50 -6
  3. data/Rakefile +9 -9
  4. data/TODO +6 -6
  5. data/lib/action_web_service.rb +4 -3
  6. data/lib/action_web_service/api.rb +248 -1
  7. data/lib/action_web_service/casting.rb +111 -0
  8. data/lib/action_web_service/client/soap_client.rb +17 -33
  9. data/lib/action_web_service/client/xmlrpc_client.rb +10 -34
  10. data/lib/action_web_service/container/delegated_container.rb +1 -1
  11. data/lib/action_web_service/dispatcher/abstract.rb +52 -72
  12. data/lib/action_web_service/dispatcher/action_controller_dispatcher.rb +71 -55
  13. data/lib/action_web_service/protocol/abstract.rb +82 -3
  14. data/lib/action_web_service/protocol/discovery.rb +2 -2
  15. data/lib/action_web_service/protocol/soap_protocol.rb +95 -22
  16. data/lib/action_web_service/protocol/soap_protocol/marshaler.rb +197 -0
  17. data/lib/action_web_service/protocol/xmlrpc_protocol.rb +56 -24
  18. data/lib/action_web_service/scaffolding.rb +237 -0
  19. data/lib/action_web_service/struct.rb +17 -4
  20. data/lib/action_web_service/support/signature_types.rb +194 -0
  21. data/lib/action_web_service/templates/scaffolds/layout.rhtml +65 -0
  22. data/lib/action_web_service/templates/scaffolds/methods.rhtml +6 -0
  23. data/lib/action_web_service/templates/scaffolds/parameters.rhtml +28 -0
  24. data/lib/action_web_service/templates/scaffolds/result.rhtml +30 -0
  25. data/lib/action_web_service/test_invoke.rb +23 -42
  26. data/test/abstract_dispatcher.rb +102 -48
  27. data/test/abstract_unit.rb +1 -1
  28. data/test/api_test.rb +40 -7
  29. data/test/casting_test.rb +82 -0
  30. data/test/client_soap_test.rb +3 -0
  31. data/test/client_xmlrpc_test.rb +5 -1
  32. data/test/dispatcher_action_controller_soap_test.rb +9 -12
  33. data/test/dispatcher_action_controller_xmlrpc_test.rb +1 -11
  34. data/test/run +1 -0
  35. data/test/scaffolded_controller_test.rb +67 -0
  36. data/test/struct_test.rb +33 -21
  37. data/test/test_invoke_test.rb +1 -1
  38. metadata +18 -31
  39. data/lib/action_web_service/api/base.rb +0 -135
  40. data/lib/action_web_service/vendor/ws.rb +0 -4
  41. data/lib/action_web_service/vendor/ws/common.rb +0 -8
  42. data/lib/action_web_service/vendor/ws/encoding.rb +0 -3
  43. data/lib/action_web_service/vendor/ws/encoding/abstract.rb +0 -26
  44. data/lib/action_web_service/vendor/ws/encoding/soap_rpc_encoding.rb +0 -90
  45. data/lib/action_web_service/vendor/ws/encoding/xmlrpc_encoding.rb +0 -53
  46. data/lib/action_web_service/vendor/ws/marshaling.rb +0 -3
  47. data/lib/action_web_service/vendor/ws/marshaling/abstract.rb +0 -17
  48. data/lib/action_web_service/vendor/ws/marshaling/soap_marshaling.rb +0 -277
  49. data/lib/action_web_service/vendor/ws/marshaling/xmlrpc_marshaling.rb +0 -116
  50. data/lib/action_web_service/vendor/ws/types.rb +0 -165
  51. data/test/ws/abstract_encoding.rb +0 -68
  52. data/test/ws/abstract_unit.rb +0 -13
  53. data/test/ws/gencov +0 -3
  54. data/test/ws/run +0 -5
  55. data/test/ws/soap_marshaling_test.rb +0 -91
  56. data/test/ws/soap_rpc_encoding_test.rb +0 -47
  57. data/test/ws/types_test.rb +0 -43
  58. data/test/ws/xmlrpc_encoding_test.rb +0 -34
@@ -1,135 +0,0 @@
1
- module ActionWebService # :nodoc:
2
- module API # :nodoc:
3
- # A web service API class specifies the methods that will be available for
4
- # invocation for an API. It also contains metadata such as the method type
5
- # signature hints.
6
- #
7
- # It is not intended to be instantiated.
8
- #
9
- # It is attached to web service implementation classes like
10
- # ActionWebService::Base and ActionController::Base derivatives by using
11
- # ClassMethods#web_service_api.
12
- class Base
13
- # Whether to transform the public API method names into camel-cased names
14
- class_inheritable_option :inflect_names, true
15
-
16
- # Whether to allow ActiveRecord::Base models in <tt>:expects</tt>.
17
- # The default is +false+, you should be aware of the security implications
18
- # of allowing this, and ensure that you don't allow remote callers to
19
- # easily overwrite data they should not have access to.
20
- class_inheritable_option :allow_active_record_expects, false
21
-
22
- # If present, the name of a method to call when the remote caller
23
- # tried to call a nonexistent method. Semantically equivalent to
24
- # +method_missing+.
25
- class_inheritable_option :default_api_method
26
-
27
- # Disallow instantiation
28
- private_class_method :new, :allocate
29
-
30
- class << self
31
- # API methods have a +name+, which must be the Ruby method name to use when
32
- # performing the invocation on the web service object.
33
- #
34
- # The signatures for the method input parameters and return value can
35
- # by specified in +options+.
36
- #
37
- # A signature is an array of one or more parameter specifiers.
38
- # A parameter specifier can be one of the following:
39
- #
40
- # * A symbol or string of representing one of the Action Web Service base types.
41
- # See ActionWebService::Signature for a canonical list of the base types.
42
- # * The Class object of the parameter type
43
- # * A single-element Array containing one of the two preceding items. This
44
- # will cause Action Web Service to treat the parameter at that position
45
- # as an array containing only values of the given type.
46
- # * A Hash containing as key the name of the parameter, and as value
47
- # one of the three preceding items
48
- #
49
- # If no method input parameter or method return value signatures are given,
50
- # the method is assumed to take no parameters and/or return no values of
51
- # interest, and any values that are received by the server will be
52
- # discarded and ignored.
53
- #
54
- # Valid options:
55
- # [<tt>:expects</tt>] Signature for the method input parameters
56
- # [<tt>:returns</tt>] Signature for the method return value
57
- # [<tt>:expects_and_returns</tt>] Signature for both input parameters and return value
58
- def api_method(name, options={})
59
- validate_options([:expects, :returns, :expects_and_returns], options.keys)
60
- if options[:expects_and_returns]
61
- expects = options[:expects_and_returns]
62
- returns = options[:expects_and_returns]
63
- else
64
- expects = options[:expects]
65
- returns = options[:returns]
66
- end
67
- expects = canonical_signature(expects)
68
- returns = canonical_signature(returns)
69
- if expects
70
- expects.each do |param|
71
- klass = WS::BaseTypes.canonical_param_type_class(param)
72
- klass = klass[0] if klass.is_a?(Array)
73
- if klass.ancestors.include?(ActiveRecord::Base) && !allow_active_record_expects
74
- raise(ActionWebServiceError, "ActiveRecord model classes not allowed in :expects")
75
- end
76
- end
77
- end
78
- name = name.to_sym
79
- public_name = public_api_method_name(name)
80
- info = { :expects => expects, :returns => returns }
81
- write_inheritable_hash("api_methods", name => info)
82
- write_inheritable_hash("api_public_method_names", public_name => name)
83
- end
84
-
85
- # Whether the given method name is a service method on this API
86
- def has_api_method?(name)
87
- api_methods.has_key?(name)
88
- end
89
-
90
- # Whether the given public method name has a corresponding service method
91
- # on this API
92
- def has_public_api_method?(public_name)
93
- api_public_method_names.has_key?(public_name)
94
- end
95
-
96
- # The corresponding public method name for the given service method name
97
- def public_api_method_name(name)
98
- if inflect_names
99
- name.to_s.camelize
100
- else
101
- name.to_s
102
- end
103
- end
104
-
105
- # The corresponding service method name for the given public method name
106
- def api_method_name(public_name)
107
- api_public_method_names[public_name]
108
- end
109
-
110
- # A Hash containing all service methods on this API, and their
111
- # associated metadata.
112
- def api_methods
113
- read_inheritable_attribute("api_methods") || {}
114
- end
115
-
116
- private
117
- def api_public_method_names
118
- read_inheritable_attribute("api_public_method_names") || {}
119
- end
120
-
121
- def validate_options(valid_option_keys, supplied_option_keys)
122
- unknown_option_keys = supplied_option_keys - valid_option_keys
123
- unless unknown_option_keys.empty?
124
- raise(ActionWebServiceError, "Unknown options: #{unknown_option_keys}")
125
- end
126
- end
127
-
128
- def canonical_signature(signature)
129
- return nil if signature.nil?
130
- signature.map{|spec| WS::BaseTypes.canonical_param_type_spec(spec)}
131
- end
132
- end
133
- end
134
- end
135
- end
@@ -1,4 +0,0 @@
1
- require 'ws/common'
2
- require 'ws/types'
3
- require 'ws/marshaling'
4
- require 'ws/encoding'
@@ -1,8 +0,0 @@
1
- module WS
2
- class WSError < StandardError
3
- end
4
-
5
- def self.derived_from?(ancestor, child)
6
- child.ancestors.include?(ancestor)
7
- end
8
- end
@@ -1,3 +0,0 @@
1
- require 'ws/encoding/abstract'
2
- require 'ws/encoding/soap_rpc_encoding'
3
- require 'ws/encoding/xmlrpc_encoding'
@@ -1,26 +0,0 @@
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
@@ -1,90 +0,0 @@
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
@@ -1,53 +0,0 @@
1
- require 'xmlrpc/marshal'
2
-
3
- module WS
4
- module Encoding
5
- class XmlRpcError < WSError
6
- end
7
-
8
- class XmlRpcEncoding < AbstractEncoding
9
- def encode_rpc_call(method_name, params)
10
- XMLRPC::Marshal.dump_call(method_name, *params)
11
- end
12
-
13
- def decode_rpc_call(obj)
14
- method_name, params = XMLRPC::Marshal.load_call(obj) rescue nil
15
- unless method_name && params
16
- raise(XmlRpcError, "Malformed XML-RPC request")
17
- end
18
- i = 0
19
- params = params.map do |value|
20
- param = XmlRpcDecodedParam.new("param#{i}", value)
21
- i += 1
22
- param
23
- end
24
- [method_name, params]
25
- end
26
-
27
- def encode_rpc_response(method_name, return_value)
28
- if return_value.nil?
29
- XMLRPC::Marshal.dump_response(true)
30
- else
31
- XMLRPC::Marshal.dump_response(return_value)
32
- end
33
- end
34
-
35
- def decode_rpc_response(obj)
36
- return_value = XMLRPC::Marshal.load_response(obj) rescue nil
37
- if return_value.nil?
38
- raise(XmlRpcError, "Malformed XML-RPC response")
39
- end
40
- [nil, XmlRpcDecodedParam.new('return', return_value)]
41
- end
42
- end
43
-
44
- class XmlRpcDecodedParam
45
- attr :param
46
-
47
- def initialize(name, value)
48
- info = ParamInfo.new(name, value.class)
49
- @param = Param.new(value, info)
50
- end
51
- end
52
- end
53
- end
@@ -1,3 +0,0 @@
1
- require 'ws/marshaling/abstract'
2
- require 'ws/marshaling/soap_marshaling'
3
- require 'ws/marshaling/xmlrpc_marshaling'
@@ -1,17 +0,0 @@
1
- module WS
2
- module Marshaling
3
- class AbstractMarshaler
4
- def marshal(param)
5
- raise NotImplementedError
6
- end
7
-
8
- def unmarshal(param)
9
- raise NotImplementedError
10
- end
11
-
12
- def register_type(type)
13
- nil
14
- end
15
- end
16
- end
17
- end
@@ -1,277 +0,0 @@
1
- require 'soap/mapping'
2
- require 'xsd/ns'
3
-
4
- module WS
5
- module Marshaling
6
- SoapEncodingNS = 'http://schemas.xmlsoap.org/soap/encoding/'
7
-
8
- class SoapError < WSError
9
- end
10
-
11
- class SoapMarshaler < AbstractMarshaler
12
- attr :registry
13
- attr_accessor :type_namespace
14
-
15
- def initialize(type_namespace='')
16
- @type_namespace = type_namespace
17
- @registry = SOAP::Mapping::Registry.new
18
- @spec2binding = {}
19
- end
20
-
21
- def marshal(param)
22
- annotate_arrays(param.info.data, param.value)
23
- if param.value.is_a?(Exception)
24
- detail = SOAP::Mapping::SOAPException.new(param.value)
25
- soap_obj = SOAP::SOAPFault.new(
26
- SOAP::SOAPQName.new('%s:%s' % [SOAP::SOAPNamespaceTag, 'Server']),
27
- SOAP::SOAPString.new(param.value.to_s),
28
- SOAP::SOAPString.new(self.class.name),
29
- SOAP::Mapping.obj2soap(detail))
30
- else
31
- soap_obj = SOAP::Mapping.obj2soap(param.value, @registry)
32
- end
33
- SoapForeignObject.new(param, soap_obj)
34
- end
35
-
36
- def unmarshal(obj)
37
- param = obj.param
38
- soap_object = obj.soap_object
39
- soap_type = soap_object ? soap_object.type : nil
40
- value = soap_object ? SOAP::Mapping.soap2obj(soap_object, @registry) : nil
41
- param.value = value
42
- param.info.type = value.class
43
- mapping = @registry.find_mapped_soap_class(param.info.type) rescue nil
44
- if soap_type && soap_type.name == 'Array' && soap_type.namespace == SoapEncodingNS
45
- param.info.data = SoapBinding.new(self, soap_object.arytype, Array, mapping)
46
- else
47
- param.info.data = SoapBinding.new(self, soap_type, value.class, mapping)
48
- end
49
- param
50
- end
51
-
52
- def register_type(spec)
53
- if @spec2binding.has_key?(spec)
54
- return @spec2binding[spec]
55
- end
56
-
57
- klass = BaseTypes.canonical_param_type_class(spec)
58
- if klass.is_a?(Array)
59
- type_class = klass[0]
60
- else
61
- type_class = klass
62
- end
63
-
64
- type_binding = nil
65
- if (mapping = @registry.find_mapped_soap_class(type_class) rescue nil)
66
- qname = mapping[2] ? mapping[2][:type] : nil
67
- qname ||= soap_base_type_name(mapping[0])
68
- type_binding = SoapBinding.new(self, qname, type_class, mapping)
69
- else
70
- qname = XSD::QName.new(@type_namespace, soap_type_name(type_class.name))
71
- @registry.add(type_class,
72
- SOAP::SOAPStruct,
73
- typed_struct_factory(type_class),
74
- { :type => qname })
75
- mapping = @registry.find_mapped_soap_class(type_class)
76
- type_binding = SoapBinding.new(self, qname, type_class, mapping)
77
- end
78
-
79
- array_binding = nil
80
- if klass.is_a?(Array)
81
- array_mapping = @registry.find_mapped_soap_class(Array) rescue nil
82
- if (array_mapping && !array_mapping[1].is_a?(SoapTypedArrayFactory)) || array_mapping.nil?
83
- @registry.set(Array,
84
- SOAP::SOAPArray,
85
- SoapTypedArrayFactory.new)
86
- array_mapping = @registry.find_mapped_soap_class(Array)
87
- end
88
- qname = XSD::QName.new(@type_namespace, soap_type_name(type_class.name) + 'Array')
89
- array_binding = SoapBinding.new(self, qname, Array, array_mapping, type_binding)
90
- end
91
-
92
- @spec2binding[spec] = array_binding ? array_binding : type_binding
93
- @spec2binding[spec]
94
- end
95
-
96
- protected
97
- def annotate_arrays(binding, value)
98
- if binding.is_typed_array?
99
- mark_typed_array(value, binding.element_binding.qname)
100
- if binding.element_binding.is_custom_type?
101
- value.each do |element|
102
- annotate_arrays(register_type(element.class), element)
103
- end
104
- end
105
- elsif binding.is_typed_struct?
106
- if binding.type_class.respond_to?(:members)
107
- binding.type_class.members.each do |name, spec|
108
- member_binding = register_type(spec)
109
- member_value = value.send(name)
110
- if member_binding.is_custom_type?
111
- annotate_arrays(member_binding, member_value)
112
- end
113
- end
114
- end
115
- end
116
- end
117
-
118
- def mark_typed_array(array, qname)
119
- (class << array; self; end).class_eval do
120
- define_method(:arytype) do
121
- qname
122
- end
123
- end
124
- end
125
-
126
- def typed_struct_factory(type_class)
127
- if Object.const_defined?('ActiveRecord')
128
- if WS.derived_from?(ActiveRecord::Base, type_class)
129
- qname = XSD::QName.new(@type_namespace, soap_type_name(type_class.name))
130
- type_class.instance_variable_set('@qname', qname)
131
- return SoapActiveRecordStructFactory.new
132
- end
133
- end
134
- SOAP::Mapping::Registry::TypedStructFactory
135
- end
136
-
137
- def soap_type_name(type_name)
138
- type_name.gsub(/::/, '..')
139
- end
140
-
141
- def soap_base_type_name(type)
142
- xsd_type = type.ancestors.find{|c| c.const_defined? 'Type'}
143
- xsd_type ? xsd_type.const_get('Type') : XSD::XSDAnySimpleType::Type
144
- end
145
- end
146
-
147
- class SoapForeignObject
148
- attr_accessor :param
149
- attr_accessor :soap_object
150
-
151
- def initialize(param, soap_object)
152
- @param = param
153
- @soap_object = soap_object
154
- end
155
- end
156
-
157
- class SoapBinding
158
- attr :qname
159
- attr :type_class
160
- attr :mapping
161
- attr :element_binding
162
-
163
- def initialize(marshaler, qname, type_class, mapping, element_binding=nil)
164
- @marshaler = marshaler
165
- @qname = qname
166
- @type_class = type_class
167
- @mapping = mapping
168
- @element_binding = element_binding
169
- end
170
-
171
- def is_custom_type?
172
- is_typed_array? || is_typed_struct?
173
- end
174
-
175
- def is_typed_array?
176
- @mapping[1].is_a?(WS::Marshaling::SoapTypedArrayFactory)
177
- end
178
-
179
- def is_typed_struct?
180
- @mapping[1] == SOAP::Mapping::Registry::TypedStructFactory || \
181
- @mapping[1].is_a?(WS::Marshaling::SoapActiveRecordStructFactory)
182
- end
183
-
184
- def each_member(&block)
185
- if is_typed_struct?
186
- if @mapping[1] == SOAP::Mapping::Registry::TypedStructFactory
187
- if @type_class.respond_to?(:members)
188
- @type_class.members.each do |name, spec|
189
- yield name, spec
190
- end
191
- end
192
- elsif @mapping[1].is_a?(WS::Marshaling::SoapActiveRecordStructFactory)
193
- @type_class.columns.each do |column|
194
- yield column.name, column.klass
195
- end
196
- end
197
- end
198
- end
199
-
200
- def type_name
201
- is_custom_type? ? @qname.name : nil
202
- end
203
-
204
- def qualified_type_name(ns=nil)
205
- if is_custom_type?
206
- "#{ns ? ns : @qname.namespace}:#{@qname.name}"
207
- else
208
- ns = XSD::NS.new
209
- ns.assign(XSD::Namespace, SOAP::XSDNamespaceTag)
210
- xsd_klass = mapping[0].ancestors.find{|c| c.const_defined?('Type')}
211
- return ns.name(XSD::AnyTypeName) unless xsd_klass
212
- ns.name(xsd_klass.const_get('Type'))
213
- end
214
- end
215
- end
216
-
217
- class SoapActiveRecordStructFactory < SOAP::Mapping::Factory
218
- def obj2soap(soap_class, obj, info, map)
219
- unless obj.is_a?(ActiveRecord::Base)
220
- return nil
221
- end
222
- soap_obj = soap_class.new(obj.class.instance_variable_get('@qname'))
223
- obj.class.columns.each do |column|
224
- key = column.name.to_s
225
- value = obj.send(key)
226
- soap_obj[key] = SOAP::Mapping._obj2soap(value, map)
227
- end
228
- soap_obj
229
- end
230
-
231
- def soap2obj(obj_class, node, info, map)
232
- unless node.type == obj_class.instance_variable_get('@qname')
233
- return false
234
- end
235
- obj = obj_class.new
236
- node.each do |key, value|
237
- obj[key] = value.data
238
- end
239
- obj.instance_variable_set('@new_record', false)
240
- return true, obj
241
- end
242
- end
243
-
244
- class SoapTypedArrayFactory < SOAP::Mapping::Factory
245
- def obj2soap(soap_class, obj, info, map)
246
- unless obj.respond_to?(:arytype)
247
- return nil
248
- end
249
- soap_obj = soap_class.new(SOAP::ValueArrayName, 1, obj.arytype)
250
- mark_marshalled_obj(obj, soap_obj)
251
- obj.each do |item|
252
- child = SOAP::Mapping._obj2soap(item, map)
253
- soap_obj.add(child)
254
- end
255
- soap_obj
256
- end
257
-
258
- def soap2obj(obj_class, node, info, map)
259
- return false
260
- end
261
- end
262
-
263
- module ActiveRecordSoapMarshallable
264
- def allocate
265
- obj = super
266
- attrs = {}
267
- self.columns.each{|c| attrs[c.name.to_s] = c.default}
268
- obj.instance_variable_set('@attributes', attrs)
269
- obj
270
- end
271
- end
272
-
273
- if Object.const_defined?('ActiveRecord')
274
- ActiveRecord::Base.extend(ActiveRecordSoapMarshallable)
275
- end
276
- end
277
- end