diff options
Diffstat (limited to 'actionwebservice')
8 files changed, 72 insertions, 10 deletions
diff --git a/actionwebservice/CHANGELOG b/actionwebservice/CHANGELOG index 6906197b8b..699a675fc5 100644 --- a/actionwebservice/CHANGELOG +++ b/actionwebservice/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Add support for a :base64 signature type #1272 [Shugo Maeda] + * Fix that boolean fields were not rendered correctly in scaffolding * Fix that scaffolding was not working for :delegated dispatching diff --git a/actionwebservice/lib/action_web_service/casting.rb b/actionwebservice/lib/action_web_service/casting.rb index 91f36d113a..c76dd84581 100644 --- a/actionwebservice/lib/action_web_service/casting.rb +++ b/actionwebservice/lib/action_web_service/casting.rb @@ -63,6 +63,12 @@ module ActionWebService # :nodoc: Integer(value) when :string value.to_s + when :base64 + if value.is_a?(ActionWebService::Base64) + value + else + ActionWebService::Base64.new(value.to_s) + end when :bool return false if value.nil? return value if value == true || value == false diff --git a/actionwebservice/lib/action_web_service/protocol/soap_protocol/marshaler.rb b/actionwebservice/lib/action_web_service/protocol/soap_protocol/marshaler.rb index 5d9a80b007..eb8f6f1147 100644 --- a/actionwebservice/lib/action_web_service/protocol/soap_protocol/marshaler.rb +++ b/actionwebservice/lib/action_web_service/protocol/soap_protocol/marshaler.rb @@ -11,6 +11,7 @@ module ActionWebService @type_namespace = type_namespace || 'urn:ActionWebService' @registry = SOAP::Mapping::Registry.new @type2binding = {} + register_static_factories end def soap_to_ruby(obj) @@ -43,13 +44,7 @@ module ActionWebService array_binding = nil if type.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 + array_mapping = @registry.find_mapped_soap_class(Array) qname = XSD::QName.new(@type_namespace, soap_type_name(type.element_type.type_class.name) + 'Array') array_binding = SoapBinding.new(self, qname, type, array_mapping, type_binding) end @@ -104,6 +99,21 @@ module ActionWebService def soap_type_name(type_name) type_name.gsub(/::/, '..') end + + def register_static_factories + @registry.add(ActionWebService::Base64, + SOAP::SOAPBase64, + SoapBase64Factory.new, + nil) + mapping = @registry.find_mapped_soap_class(ActionWebService::Base64) + @type2binding[ActionWebService::Base64] = + SoapBinding.new(self, SOAP::SOAPBase64::Type, + ActionWebService::Base64, mapping) + @registry.add(Array, + SOAP::SOAPArray, + SoapTypedArrayFactory.new, + nil) + end end class SoapBinding @@ -130,6 +140,7 @@ module ActionWebService else ns = XSD::NS.new ns.assign(XSD::Namespace, SOAP::XSDNamespaceTag) + ns.assign(SOAP::EncodingNamespace, "soapenc") 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')) @@ -192,6 +203,22 @@ module ActionWebService end end + class SoapBase64Factory < SOAP::Mapping::Factory + def obj2soap(soap_class, obj, info, map) + unless obj.is_a?(ActionWebService::Base64) + return nil + end + return soap_class.new(obj) + end + + def soap2obj(obj_class, node, info, map) + unless node.type == SOAP::SOAPBase64::Type + return false + end + return true, obj_class.new(node.string) + end + end + end end end diff --git a/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb b/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb index d20fe05726..dec94ccad0 100644 --- a/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb +++ b/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb @@ -67,6 +67,8 @@ module ActionWebService # :nodoc: struct[key.to_s] = member_value end struct + elsif value.is_a?(ActionWebService::Base64) + XMLRPC::Base64.new(value) elsif value.is_a?(Exception) && !value.is_a?(XMLRPC::FaultException) XMLRPC::FaultException.new(2, value.message) else diff --git a/actionwebservice/lib/action_web_service/support/signature_types.rb b/actionwebservice/lib/action_web_service/support/signature_types.rb index 253e9dcb6a..e0f0c2ecd8 100644 --- a/actionwebservice/lib/action_web_service/support/signature_types.rb +++ b/actionwebservice/lib/action_web_service/support/signature_types.rb @@ -40,8 +40,10 @@ module ActionWebService # :nodoc: case name when :int, :integer, :fixnum, :bignum :int - when :string, :base64 + when :string :string + when :base64 + :base64 when :bool, :boolean :bool when :float, :double @@ -73,6 +75,8 @@ module ActionWebService # :nodoc: :int elsif klass == String :string + elsif klass == Base64 + :base64 elsif klass == TrueClass || klass == FalseClass :bool elsif derived_from?(Float, klass) || derived_from?(Precision, klass) || derived_from?(Numeric, klass) @@ -94,6 +98,8 @@ module ActionWebService # :nodoc: Integer when :string String + when :base64 + Base64 when :bool TrueClass when :float @@ -197,4 +203,7 @@ module ActionWebService # :nodoc: true end end + + class Base64 < String + end end diff --git a/actionwebservice/test/abstract_dispatcher.rb b/actionwebservice/test/abstract_dispatcher.rb index 7d02943d0a..78243ee497 100644 --- a/actionwebservice/test/abstract_dispatcher.rb +++ b/actionwebservice/test/abstract_dispatcher.rb @@ -56,6 +56,8 @@ module DispatcherTest api_method :hash_struct_return, :returns => [[Person]] api_method :thrower api_method :void + api_method :hex, :expects => [:base64], :returns => [:string] + api_method :unhex, :expects => [:string], :returns => [:base64] end class VirtualAPI < ActionWebService::API::Base @@ -216,6 +218,14 @@ module DispatcherTest @void_called = @method_params end + def hex(s) + return s.unpack("H*")[0] + end + + def unhex(s) + return [s].pack("H*") + end + protected def alwaysfail @before_filter_called = true @@ -248,6 +258,8 @@ module DispatcherCommonTests result = do_method_call(@direct_controller, 'BaseStructReturn') assert(result[0].is_a?(DispatcherTest::Person)) assert(result[1].is_a?(DispatcherTest::Person)) + assert_equal("cafe", do_method_call(@direct_controller, 'Hex', "\xca\xfe")) + assert_equal("\xca\xfe", do_method_call(@direct_controller, 'Unhex', "cafe")) end def test_direct_entrypoint diff --git a/actionwebservice/test/api_test.rb b/actionwebservice/test/api_test.rb index 83d7196273..0e58d84864 100644 --- a/actionwebservice/test/api_test.rb +++ b/actionwebservice/test/api_test.rb @@ -7,7 +7,7 @@ module APITest api_method :expects, :expects => [:int, :bool] api_method :returns, :returns => [:int, [:string]] api_method :named_signature, :expects => [{:appkey=>:int}, {:publish=>:bool}] - api_method :string_types, :expects => ['int', 'string', 'bool'] + api_method :string_types, :expects => ['int', 'string', 'bool', 'base64'] api_method :class_types, :expects => [TrueClass, Bignum, String] end end @@ -45,7 +45,7 @@ class TC_API < Test::Unit::TestCase assert_equal([Integer, [String]], API.api_methods[:returns].returns.map{|x| x.array?? [x.element_type.type_class] : x.type_class}) assert_equal([[:appkey, Integer], [:publish, TrueClass]], API.api_methods[:named_signature].expects.map{|x| [x.name, x.type_class]}) assert_equal(nil, API.api_methods[:named_signature].returns) - assert_equal([Integer, String, TrueClass], API.api_methods[:string_types].expects.map{|x| x.type_class}) + assert_equal([Integer, String, TrueClass, ActionWebService::Base64], API.api_methods[:string_types].expects.map{|x| x.type_class}) assert_equal(nil, API.api_methods[:string_types].returns) assert_equal([TrueClass, Integer, String], API.api_methods[:class_types].expects.map{|x| x.type_class}) assert_equal(nil, API.api_methods[:class_types].returns) diff --git a/actionwebservice/test/casting_test.rb b/actionwebservice/test/casting_test.rb index aa8941da17..34bad07d5b 100644 --- a/actionwebservice/test/casting_test.rb +++ b/actionwebservice/test/casting_test.rb @@ -4,6 +4,7 @@ module CastingTest class API < ActionWebService::API::Base api_method :int, :expects => [:int] api_method :str, :expects => [:string] + api_method :base64, :expects => [:base64] api_method :bool, :expects => [:bool] api_method :float, :expects => [:float] api_method :time, :expects => [:time] @@ -22,6 +23,9 @@ class TC_Casting < Test::Unit::TestCase def test_base_type_casting_valid assert_equal 10000, cast_expects(:int, '10000')[0] assert_equal '10000', cast_expects(:str, 10000)[0] + base64 = cast_expects(:base64, 10000)[0] + assert_equal '10000', base64 + assert_instance_of ActionWebService::Base64, base64 [1, '1', 'true', 'y', 'yes'].each do |val| assert_equal true, cast_expects(:bool, val)[0] end |