aboutsummaryrefslogtreecommitdiffstats
path: root/actionwebservice/lib/action_web_service/vendor
diff options
context:
space:
mode:
authorLeon Breedt <bitserf@gmail.com>2005-03-28 03:20:13 +0000
committerLeon Breedt <bitserf@gmail.com>2005-03-28 03:20:13 +0000
commit594063f23cf8e7cecd24329e801992784f420b55 (patch)
treed52e9a6fc0521d51fcc3875162adf0411ee6caa0 /actionwebservice/lib/action_web_service/vendor
parent439a216dcb65ac83d86ca04bb898e1797a87ce70 (diff)
downloadrails-594063f23cf8e7cecd24329e801992784f420b55.tar.gz
rails-594063f23cf8e7cecd24329e801992784f420b55.tar.bz2
rails-594063f23cf8e7cecd24329e801992784f420b55.zip
generalize casting code to be used by both SOAP and XML-RPC (previously only XML-RPC). switch
to better model for API methods, and improve the ability to generate protocol requests/response, will be required by upcoming scaffolding. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1030 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionwebservice/lib/action_web_service/vendor')
-rw-r--r--actionwebservice/lib/action_web_service/vendor/ws/marshaling/abstract.rb16
-rw-r--r--actionwebservice/lib/action_web_service/vendor/ws/marshaling/soap_marshaling.rb22
-rw-r--r--actionwebservice/lib/action_web_service/vendor/ws/marshaling/xmlrpc_marshaling.rb113
3 files changed, 107 insertions, 44 deletions
diff --git a/actionwebservice/lib/action_web_service/vendor/ws/marshaling/abstract.rb b/actionwebservice/lib/action_web_service/vendor/ws/marshaling/abstract.rb
index 53120e1447..e897f62297 100644
--- a/actionwebservice/lib/action_web_service/vendor/ws/marshaling/abstract.rb
+++ b/actionwebservice/lib/action_web_service/vendor/ws/marshaling/abstract.rb
@@ -1,6 +1,10 @@
module WS
module Marshaling
class AbstractMarshaler
+ def initialize
+ @base_type_caster = BaseTypeCaster.new
+ end
+
def marshal(param)
raise NotImplementedError
end
@@ -12,6 +16,18 @@ module WS
def register_type(type)
nil
end
+ alias :lookup_type :register_type
+
+ def cast_inbound_recursive(value, spec)
+ raise NotImplementedError
+ end
+
+ def cast_outbound_recursive(value, spec)
+ raise NotImplementedError
+ end
+
+ attr :base_type_caster
+ protected :base_type_caster
end
end
end
diff --git a/actionwebservice/lib/action_web_service/vendor/ws/marshaling/soap_marshaling.rb b/actionwebservice/lib/action_web_service/vendor/ws/marshaling/soap_marshaling.rb
index 4d29c78f2c..287a64291b 100644
--- a/actionwebservice/lib/action_web_service/vendor/ws/marshaling/soap_marshaling.rb
+++ b/actionwebservice/lib/action_web_service/vendor/ws/marshaling/soap_marshaling.rb
@@ -13,6 +13,7 @@ module WS
attr_accessor :type_namespace
def initialize(type_namespace='')
+ super()
@type_namespace = type_namespace
@registry = SOAP::Mapping::Registry.new
@spec2binding = {}
@@ -92,6 +93,25 @@ module WS
@spec2binding[spec] = array_binding ? array_binding : type_binding
@spec2binding[spec]
end
+ alias :lookup_type :register_type
+
+ def cast_inbound_recursive(value, spec)
+ binding = lookup_type(spec)
+ if binding.is_custom_type?
+ value
+ else
+ base_type_caster.cast(value, binding.type_class)
+ end
+ end
+
+ def cast_outbound_recursive(value, spec)
+ binding = lookup_type(spec)
+ if binding.is_custom_type?
+ value
+ else
+ base_type_caster.cast(value, binding.type_class)
+ end
+ end
protected
def annotate_arrays(binding, value)
@@ -106,7 +126,7 @@ module WS
if binding.type_class.respond_to?(:members)
binding.type_class.members.each do |name, spec|
member_binding = register_type(spec)
- member_value = value.send(name)
+ member_value = value.respond_to?('[]') ? value[name] : value.send(name)
if member_binding.is_custom_type?
annotate_arrays(member_binding, member_value)
end
diff --git a/actionwebservice/lib/action_web_service/vendor/ws/marshaling/xmlrpc_marshaling.rb b/actionwebservice/lib/action_web_service/vendor/ws/marshaling/xmlrpc_marshaling.rb
index 87154f87e1..56cc7597fb 100644
--- a/actionwebservice/lib/action_web_service/vendor/ws/marshaling/xmlrpc_marshaling.rb
+++ b/actionwebservice/lib/action_web_service/vendor/ws/marshaling/xmlrpc_marshaling.rb
@@ -5,24 +5,24 @@ module WS
class XmlRpcMarshaler < AbstractMarshaler
def initialize
- @caster = BaseTypeCaster.new
+ super()
@spec2binding = {}
end
def marshal(param)
- transform_outbound(param)
+ value = param.value
+ cast_outbound_recursive(param.value, spec_for(param)) rescue value
end
def unmarshal(obj)
- obj.param.value = transform_inbound(obj.param)
obj.param
end
def typed_unmarshal(obj, spec)
- param = obj.param
- param.info.data = register_type(spec)
- param.value = transform_inbound(param)
- param
+ obj.param.info.data = lookup_type(spec)
+ value = obj.param.value
+ obj.param.value = cast_inbound_recursive(value, spec) rescue value
+ obj.param
end
def register_type(spec)
@@ -40,60 +40,87 @@ module WS
@spec2binding[spec] = type_binding
end
+ alias :lookup_type :register_type
- def transform_outbound(param)
- binding = param.info.data
+ def cast_inbound_recursive(value, spec)
+ binding = lookup_type(spec)
case binding
when XmlRpcArrayBinding
- param.value.map{|x| cast_outbound(x, binding.element_klass)}
+ value.map{ |x| cast_inbound(x, binding.element_klass) }
when XmlRpcBinding
- cast_outbound(param.value, param.info.type)
+ cast_inbound(value, binding.klass)
end
end
- def transform_inbound(param)
- return param.value if param.info.data.nil?
- binding = param.info.data
- param.info.type = binding.klass
+ def cast_outbound_recursive(value, spec)
+ binding = lookup_type(spec)
case binding
when XmlRpcArrayBinding
- param.value.map{|x| cast_inbound(x, binding.element_klass)}
+ value.map{ |x| cast_outbound(x, binding.element_klass) }
when XmlRpcBinding
- cast_inbound(param.value, param.info.type)
+ cast_outbound(value, binding.klass)
end
end
- def cast_outbound(value, klass)
- if BaseTypes.base_type?(klass)
- @caster.cast(value, klass)
- elsif value.is_a?(Exception)
- XMLRPC::FaultException.new(2, value.message)
- elsif Object.const_defined?('ActiveRecord') && value.is_a?(ActiveRecord::Base)
- value.attributes
- else
- struct = {}
- value.instance_variables.each do |name|
- key = name.sub(/^@/, '')
- struct[key] = value.instance_variable_get(name)
+ private
+ def spec_for(param)
+ binding = param.info.data
+ binding.is_a?(XmlRpcArrayBinding) ? [binding.element_klass] : binding.klass
+ end
+
+ def cast_inbound(value, klass)
+ if BaseTypes.base_type?(klass)
+ value = value.to_time if value.is_a?(XMLRPC::DateTime)
+ base_type_caster.cast(value, klass)
+ elsif value.is_a?(XMLRPC::FaultException)
+ value
+ elsif klass.ancestors.include?(ActionWebService::Struct)
+ obj = klass.new
+ klass.members.each do |name, klass|
+ name = name.to_s
+ obj.send('%s=' % name, cast_inbound_recursive(value[name], klass))
+ end
+ obj
+ else
+ obj = klass.new
+ if obj.respond_to?(:update)
+ obj.update(value)
+ else
+ value.each do |name, val|
+ obj.send('%s=' % name.to_s, val)
+ end
+ end
+ obj
end
- struct
end
- end
- def cast_inbound(value, klass)
- if BaseTypes.base_type?(klass)
- value = value.to_time if value.is_a?(XMLRPC::DateTime)
- @caster.cast(value, klass)
- elsif value.is_a?(XMLRPC::FaultException)
- value
- else
- obj = klass.new
- value.each do |name, val|
- obj.send('%s=' % name.to_s, val)
+ def cast_outbound(value, klass)
+ if BaseTypes.base_type?(klass)
+ base_type_caster.cast(value, klass)
+ elsif value.is_a?(Exception)
+ XMLRPC::FaultException.new(2, value.message)
+ elsif Object.const_defined?('ActiveRecord') && value.is_a?(ActiveRecord::Base)
+ value.attributes
+ elsif value.is_a?(ActionWebService::Struct)
+ struct = {}
+ value.class.members.each do |name, klass|
+ name = name.to_s
+ struct[name] = cast_outbound_recursive(value[name], klass)
+ end
+ struct
+ else
+ struct = {}
+ if value.respond_to?(:each_pair)
+ value.each_pair{ |key, value| struct[key] = value }
+ else
+ value.instance_variables.each do |name|
+ key = name.sub(/^@/, '')
+ struct[key] = value.instance_variable_get(name)
+ end
+ end
+ struct
end
- obj
end
- end
end
class XmlRpcBinding