From aaea48fe9826b9e5d2d5b92795a297b8f238c58d Mon Sep 17 00:00:00 2001 From: Leon Breedt Date: Sat, 2 Apr 2005 21:03:36 +0000 Subject: * collapse 'ws' back into protocols, it just added complexity and indirection, and was hard to extend. * extract casting into seperate support file * ensure casting always does the right thing for return values, should fix interoperability issues with Ecto and possibly other XML-RPC clients * add functional unit tests for scaffolding * represent signature items with classes instead of symbols/Class objects, much more flexible * tweak logging to always show casted versions of parameters and return values, if possible. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1072 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- .../vendor/ws/marshaling/soap_marshaling.rb | 283 --------------------- 1 file changed, 283 deletions(-) delete mode 100644 actionwebservice/lib/action_web_service/vendor/ws/marshaling/soap_marshaling.rb (limited to 'actionwebservice/lib/action_web_service/vendor/ws/marshaling/soap_marshaling.rb') 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 deleted file mode 100644 index 14c8d8401d..0000000000 --- a/actionwebservice/lib/action_web_service/vendor/ws/marshaling/soap_marshaling.rb +++ /dev/null @@ -1,283 +0,0 @@ -require 'soap/mapping' -require 'xsd/ns' - -module WS - module Marshaling - SoapEncodingNS = 'http://schemas.xmlsoap.org/soap/encoding/' - - class SoapError < WSError - end - - class SoapMarshaler < AbstractMarshaler - attr :registry - attr_accessor :type_namespace - - def initialize(type_namespace='') - super() - @type_namespace = type_namespace - @registry = SOAP::Mapping::Registry.new - @spec2binding = {} - end - - def marshal(param) - annotate_arrays(param.info.data, param.value) - if param.value.is_a?(Exception) - detail = SOAP::Mapping::SOAPException.new(param.value) - soap_obj = SOAP::SOAPFault.new( - SOAP::SOAPQName.new('%s:%s' % [SOAP::SOAPNamespaceTag, 'Server']), - SOAP::SOAPString.new(param.value.to_s), - SOAP::SOAPString.new(self.class.name), - SOAP::Mapping.obj2soap(detail)) - else - soap_obj = SOAP::Mapping.obj2soap(param.value, @registry) - end - SoapForeignObject.new(param, soap_obj) - end - - def unmarshal(obj) - param = obj.param - soap_object = obj.soap_object - soap_type = soap_object ? soap_object.type : nil - value = soap_object ? SOAP::Mapping.soap2obj(soap_object, @registry) : nil - param.value = value - param.info.type = value.class - mapping = @registry.find_mapped_soap_class(param.info.type) rescue nil - if soap_type && soap_type.name == 'Array' && soap_type.namespace == SoapEncodingNS - param.info.data = SoapBinding.new(self, soap_object.arytype, Array, mapping) - else - param.info.data = SoapBinding.new(self, soap_type, value.class, mapping) - end - param - end - - def register_type(spec) - if @spec2binding.has_key?(spec) - return @spec2binding[spec] - end - - klass = BaseTypes.canonical_param_type_class(spec) - if klass.is_a?(Array) - type_class = klass[0] - else - type_class = klass - end - - type_binding = nil - if (mapping = @registry.find_mapped_soap_class(type_class) rescue nil) - qname = mapping[2] ? mapping[2][:type] : nil - qname ||= soap_base_type_name(mapping[0]) - type_binding = SoapBinding.new(self, qname, type_class, mapping) - else - qname = XSD::QName.new(@type_namespace, soap_type_name(type_class.name)) - @registry.add(type_class, - SOAP::SOAPStruct, - typed_struct_factory(type_class), - { :type => qname }) - mapping = @registry.find_mapped_soap_class(type_class) - type_binding = SoapBinding.new(self, qname, type_class, mapping) - end - - array_binding = nil - if klass.is_a?(Array) - array_mapping = @registry.find_mapped_soap_class(Array) rescue nil - if (array_mapping && !array_mapping[1].is_a?(SoapTypedArrayFactory)) || array_mapping.nil? - @registry.set(Array, - SOAP::SOAPArray, - SoapTypedArrayFactory.new) - array_mapping = @registry.find_mapped_soap_class(Array) - end - qname = XSD::QName.new(@type_namespace, soap_type_name(type_class.name) + 'Array') - array_binding = SoapBinding.new(self, qname, Array, array_mapping, type_binding) - end - - @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) - if binding.is_typed_array? - mark_typed_array(value, binding.element_binding.qname) - if binding.element_binding.is_custom_type? - value.each do |element| - annotate_arrays(register_type(element.class), element) - end - end - elsif binding.is_typed_struct? - if binding.type_class.respond_to?(:members) - binding.type_class.members.each do |name, spec| - member_binding = register_type(spec) - member_value = value.respond_to?('[]') ? value[name] : value.send(name) - if member_binding.is_custom_type? - annotate_arrays(member_binding, member_value) - end - end - end - end - end - - def mark_typed_array(array, qname) - (class << array; self; end).class_eval do - define_method(:arytype) do - qname - end - end - end - - def typed_struct_factory(type_class) - if Object.const_defined?('ActiveRecord') - if WS.derived_from?(ActiveRecord::Base, type_class) - qname = XSD::QName.new(@type_namespace, soap_type_name(type_class.name)) - type_class.instance_variable_set('@qname', qname) - return SoapActiveRecordStructFactory.new - end - end - SOAP::Mapping::Registry::TypedStructFactory - end - - def soap_type_name(type_name) - type_name.gsub(/::/, '..') - end - - def soap_base_type_name(type) - xsd_type = type.ancestors.find{|c| c.const_defined? 'Type'} - xsd_type ? xsd_type.const_get('Type') : XSD::XSDAnySimpleType::Type - end - end - - class SoapForeignObject - attr_accessor :param - attr_accessor :soap_object - - def initialize(param, soap_object) - @param = param - @soap_object = soap_object - end - end - - class SoapBinding - attr :qname - attr :type_class - attr :mapping - attr :element_binding - - def initialize(marshaler, qname, type_class, mapping, element_binding=nil) - @marshaler = marshaler - @qname = qname - @type_class = type_class - @mapping = mapping - @element_binding = element_binding - end - - def is_custom_type? - is_typed_array? || is_typed_struct? - end - - def is_typed_array? - @mapping[1].is_a?(WS::Marshaling::SoapTypedArrayFactory) - end - - def is_typed_struct? - @mapping[1] == SOAP::Mapping::Registry::TypedStructFactory || \ - @mapping[1].is_a?(WS::Marshaling::SoapActiveRecordStructFactory) - end - - def each_member(&block) - if is_typed_struct? - if @mapping[1] == SOAP::Mapping::Registry::TypedStructFactory - if @type_class.respond_to?(:members) - @type_class.members.each do |name, spec| - yield name, spec - end - end - elsif @mapping[1].is_a?(WS::Marshaling::SoapActiveRecordStructFactory) - @type_class.columns.each do |column| - yield column.name, column.klass - end - end - end - end - - def type_name - is_custom_type? ? @qname.name : nil - end - - def qualified_type_name(ns=nil) - if is_custom_type? - "#{ns ? ns : @qname.namespace}:#{@qname.name}" - else - ns = XSD::NS.new - ns.assign(XSD::Namespace, SOAP::XSDNamespaceTag) - xsd_klass = mapping[0].ancestors.find{|c| c.const_defined?('Type')} - return ns.name(XSD::AnyTypeName) unless xsd_klass - ns.name(xsd_klass.const_get('Type')) - end - end - end - - class SoapActiveRecordStructFactory < SOAP::Mapping::Factory - def obj2soap(soap_class, obj, info, map) - unless obj.is_a?(ActiveRecord::Base) - return nil - end - soap_obj = soap_class.new(obj.class.instance_variable_get('@qname')) - obj.class.columns.each do |column| - key = column.name.to_s - value = obj.send(key) - soap_obj[key] = SOAP::Mapping._obj2soap(value, map) - end - soap_obj - end - - def soap2obj(obj_class, node, info, map) - unless node.type == obj_class.instance_variable_get('@qname') - return false - end - obj = obj_class.new - node.each do |key, value| - obj[key] = value.data - end - obj.instance_variable_set('@new_record', false) - return true, obj - end - end - - class SoapTypedArrayFactory < SOAP::Mapping::Factory - def obj2soap(soap_class, obj, info, map) - unless obj.respond_to?(:arytype) - return nil - end - soap_obj = soap_class.new(SOAP::ValueArrayName, 1, obj.arytype) - mark_marshalled_obj(obj, soap_obj) - obj.each do |item| - child = SOAP::Mapping._obj2soap(item, map) - soap_obj.add(child) - end - soap_obj - end - - def soap2obj(obj_class, node, info, map) - return false - end - end - end -end -- cgit v1.2.3