Skip to content
This repository
Browse code

add base64 signature type (thanks, Shugo Maeda!)

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1293 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
commit 47a7084b94b8cd0dfc43e0b8f1775eef31c5170d 1 parent 8a41ea4
Leon Breedt authored May 07, 2005
2  actionwebservice/CHANGELOG
... ...
@@ -1,5 +1,7 @@
1 1
 *SVN*
2 2
 
  3
+* Add support for a :base64 signature type #1272 [Shugo Maeda]
  4
+
3 5
 * Fix that boolean fields were not rendered correctly in scaffolding
4 6
 
5 7
 * Fix that scaffolding was not working for :delegated dispatching
6  actionwebservice/lib/action_web_service/casting.rb
@@ -63,6 +63,12 @@ def cast_base_type(value, signature_type) # :nodoc:
63 63
             Integer(value)
64 64
           when :string
65 65
             value.to_s
  66
+          when :base64
  67
+            if value.is_a?(ActionWebService::Base64)
  68
+              value
  69
+            else
  70
+              ActionWebService::Base64.new(value.to_s)
  71
+            end
66 72
           when :bool
67 73
             return false if value.nil?
68 74
             return value if value == true || value == false
41  actionwebservice/lib/action_web_service/protocol/soap_protocol/marshaler.rb
@@ -11,6 +11,7 @@ def initialize(type_namespace=nil)
11 11
           @type_namespace = type_namespace || 'urn:ActionWebService'
12 12
           @registry = SOAP::Mapping::Registry.new
13 13
           @type2binding = {}
  14
+          register_static_factories
14 15
         end
15 16
 
16 17
         def soap_to_ruby(obj)
@@ -43,13 +44,7 @@ def register_type(type)
43 44
 
44 45
           array_binding = nil
45 46
           if type.array?
46  
-            array_mapping = @registry.find_mapped_soap_class(Array) rescue nil
47  
-            if (array_mapping && !array_mapping[1].is_a?(SoapTypedArrayFactory)) || array_mapping.nil?
48  
-              @registry.set(Array,
49  
-                            SOAP::SOAPArray,
50  
-                            SoapTypedArrayFactory.new)
51  
-              array_mapping = @registry.find_mapped_soap_class(Array)
52  
-            end
  47
+            array_mapping = @registry.find_mapped_soap_class(Array)
53 48
             qname = XSD::QName.new(@type_namespace, soap_type_name(type.element_type.type_class.name) + 'Array')
54 49
             array_binding = SoapBinding.new(self, qname, type, array_mapping, type_binding)
55 50
           end
@@ -104,6 +99,21 @@ def soap_base_type_name(type)
104 99
           def soap_type_name(type_name)
105 100
             type_name.gsub(/::/, '..')
106 101
           end
  102
+
  103
+          def register_static_factories
  104
+            @registry.add(ActionWebService::Base64,
  105
+                          SOAP::SOAPBase64,
  106
+                          SoapBase64Factory.new,
  107
+                          nil)
  108
+            mapping = @registry.find_mapped_soap_class(ActionWebService::Base64)
  109
+            @type2binding[ActionWebService::Base64] =
  110
+              SoapBinding.new(self, SOAP::SOAPBase64::Type,
  111
+                              ActionWebService::Base64, mapping)
  112
+            @registry.add(Array,
  113
+                          SOAP::SOAPArray,
  114
+                          SoapTypedArrayFactory.new,
  115
+                          nil)
  116
+          end
107 117
       end
108 118
 
109 119
       class SoapBinding
@@ -130,6 +140,7 @@ def qualified_type_name(ns=nil)
130 140
           else
131 141
             ns = XSD::NS.new
132 142
             ns.assign(XSD::Namespace, SOAP::XSDNamespaceTag)
  143
+            ns.assign(SOAP::EncodingNamespace, "soapenc")
133 144
             xsd_klass = mapping[0].ancestors.find{|c| c.const_defined?('Type')}
134 145
             return ns.name(XSD::AnyTypeName) unless xsd_klass
135 146
             ns.name(xsd_klass.const_get('Type'))
@@ -192,6 +203,22 @@ def soap2obj(obj_class, node, info, map)
192 203
         end
193 204
       end
194 205
 
  206
+      class SoapBase64Factory < SOAP::Mapping::Factory
  207
+        def obj2soap(soap_class, obj, info, map)
  208
+          unless obj.is_a?(ActionWebService::Base64)
  209
+            return nil
  210
+          end
  211
+          return soap_class.new(obj)
  212
+        end
  213
+
  214
+        def soap2obj(obj_class, node, info, map)
  215
+          unless node.type == SOAP::SOAPBase64::Type
  216
+            return false
  217
+          end
  218
+          return true, obj_class.new(node.string)
  219
+        end
  220
+      end
  221
+
195 222
     end
196 223
   end
197 224
 end
2  actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb
@@ -67,6 +67,8 @@ def value_to_xmlrpc_wire_format(value, value_type)
67 67
                 struct[key.to_s] = member_value
68 68
               end
69 69
               struct
  70
+            elsif value.is_a?(ActionWebService::Base64)
  71
+              XMLRPC::Base64.new(value)
70 72
             elsif value.is_a?(Exception) && !value.is_a?(XMLRPC::FaultException)
71 73
               XMLRPC::FaultException.new(2, value.message)
72 74
             else
11  actionwebservice/lib/action_web_service/support/signature_types.rb
@@ -40,8 +40,10 @@ def canonical_type_name(name)
40 40
       case name
41 41
         when :int, :integer, :fixnum, :bignum
42 42
           :int
43  
-        when :string, :base64
  43
+        when :string
44 44
           :string
  45
+        when :base64
  46
+          :base64
45 47
         when :bool, :boolean
46 48
           :bool
47 49
         when :float, :double
@@ -73,6 +75,8 @@ def class_to_type_name(klass)
73 75
         :int
74 76
       elsif klass == String
75 77
         :string
  78
+      elsif klass == Base64
  79
+        :base64
76 80
       elsif klass == TrueClass || klass == FalseClass
77 81
         :bool
78 82
       elsif derived_from?(Float, klass) || derived_from?(Precision, klass) || derived_from?(Numeric, klass)
@@ -94,6 +98,8 @@ def type_name_to_class(name)
94 98
         Integer
95 99
       when :string
96 100
         String
  101
+      when :base64
  102
+        Base64
97 103
       when :bool
98 104
         TrueClass
99 105
       when :float
@@ -197,4 +203,7 @@ def structured?
197 203
       true
198 204
     end
199 205
   end
  206
+
  207
+  class Base64 < String
  208
+  end
200 209
 end
12  actionwebservice/test/abstract_dispatcher.rb
@@ -56,6 +56,8 @@ class DirectAPI < ActionWebService::API::Base
56 56
     api_method :hash_struct_return, :returns => [[Person]]
57 57
     api_method :thrower
58 58
     api_method :void
  59
+    api_method :hex, :expects => [:base64], :returns => [:string]
  60
+    api_method :unhex, :expects => [:string], :returns => [:base64]
59 61
   end
60 62
 
61 63
   class VirtualAPI < ActionWebService::API::Base
@@ -216,6 +218,14 @@ def void
216 218
       @void_called = @method_params
217 219
     end
218 220
 
  221
+    def hex(s)
  222
+      return s.unpack("H*")[0]
  223
+    end
  224
+
  225
+    def unhex(s)
  226
+      return [s].pack("H*")
  227
+    end
  228
+
219 229
     protected
220 230
       def alwaysfail
221 231
         @before_filter_called = true
@@ -248,6 +258,8 @@ def test_direct_dispatching
248 258
     result = do_method_call(@direct_controller, 'BaseStructReturn')
249 259
     assert(result[0].is_a?(DispatcherTest::Person))
250 260
     assert(result[1].is_a?(DispatcherTest::Person))
  261
+    assert_equal("cafe", do_method_call(@direct_controller, 'Hex', "\xca\xfe"))
  262
+    assert_equal("\xca\xfe", do_method_call(@direct_controller, 'Unhex', "cafe"))
251 263
   end
252 264
 
253 265
   def test_direct_entrypoint
4  actionwebservice/test/api_test.rb
@@ -7,7 +7,7 @@ class API < ActionWebService::API::Base
7 7
     api_method :expects,             :expects => [:int, :bool]
8 8
     api_method :returns,             :returns => [:int, [:string]]
9 9
     api_method :named_signature,     :expects => [{:appkey=>:int}, {:publish=>:bool}]
10  
-    api_method :string_types,        :expects => ['int', 'string', 'bool']
  10
+    api_method :string_types,        :expects => ['int', 'string', 'bool', 'base64']
11 11
     api_method :class_types,         :expects => [TrueClass, Bignum, String]
12 12
   end
13 13
 end
@@ -45,7 +45,7 @@ def test_signature_canonicalization
45 45
     assert_equal([Integer, [String]], API.api_methods[:returns].returns.map{|x| x.array?? [x.element_type.type_class] : x.type_class})
46 46
     assert_equal([[:appkey, Integer], [:publish, TrueClass]], API.api_methods[:named_signature].expects.map{|x| [x.name, x.type_class]})
47 47
     assert_equal(nil, API.api_methods[:named_signature].returns)
48  
-    assert_equal([Integer, String, TrueClass], API.api_methods[:string_types].expects.map{|x| x.type_class})
  48
+    assert_equal([Integer, String, TrueClass, ActionWebService::Base64], API.api_methods[:string_types].expects.map{|x| x.type_class})
49 49
     assert_equal(nil, API.api_methods[:string_types].returns)
50 50
     assert_equal([TrueClass, Integer, String], API.api_methods[:class_types].expects.map{|x| x.type_class})
51 51
     assert_equal(nil, API.api_methods[:class_types].returns)
4  actionwebservice/test/casting_test.rb
@@ -4,6 +4,7 @@ module CastingTest
4 4
   class API < ActionWebService::API::Base
5 5
     api_method :int,       :expects => [:int]
6 6
     api_method :str,       :expects => [:string]
  7
+    api_method :base64,    :expects => [:base64]
7 8
     api_method :bool,      :expects => [:bool]
8 9
     api_method :float,     :expects => [:float]
9 10
     api_method :time,      :expects => [:time]
@@ -22,6 +23,9 @@ class TC_Casting < Test::Unit::TestCase
22 23
   def test_base_type_casting_valid
23 24
     assert_equal 10000,   cast_expects(:int, '10000')[0]
24 25
     assert_equal '10000', cast_expects(:str, 10000)[0]
  26
+    base64 = cast_expects(:base64, 10000)[0]
  27
+    assert_equal '10000', base64
  28
+    assert_instance_of ActionWebService::Base64, base64
25 29
     [1, '1', 'true', 'y', 'yes'].each do |val|
26 30
       assert_equal true, cast_expects(:bool, val)[0]
27 31
     end

0 notes on commit 47a7084

Please sign in to comment.
Something went wrong with that request. Please try again.