Patches: Browse | Submit New | Admin

[#17631] Add support for typed Java exceptions

Date:
2008-01-30 19:25
Priority:
3
Submitted By:
Nobody
Assigned To:
Nobody (None)
Category:
None
State:
Open
Summary:
Add support for typed Java exceptions

Detailed description
When talking to the Java Hessian implementation any Java exception is transmitted in the "details" section
of a fault.  Additionally, the Hessian type is transmitted in the "t" type section of arrays and maps.  However,
these fault details and array/map type are ignored by the Ruby Hessian library. This patch exposes the details and type
values to the developer.

Add A Comment: Notepad

Please login


Followup

Message
Date: 2008-01-30 19:29
Sender: Larry Karnowski

Wait, and the file didn't attach?  (I'm not very impressed with
this patch submission tool.)  Here's the patch:

Index: test/test_hessian_parser.rb
=================================================================
==
--- test/test_hessian_parser.rb (revision 26)
+++ test/test_hessian_parser.rb (working copy)
@@ -34,22 +34,33 @@
     assert_equal 520000, time.usec
   end
   def test_integer_array
-    assert_equal [ 1, 2, 3 ], parse([
"r\001\000Vt\000\004[intl\000\000\000\003",
+    array = parse([ "r\001\000Vt\000\004[intl\000\000\000\0
03",
       "I\000\000\000\001I\000\000\000\002I\000\000\000\003z
z" ].join)
+    assert_equal [ 1, 2, 3 ], array
+    assert_equal "[int", array.hessian_type
   end
   def test_array
-    assert_equal [ 'sillen', 32 ], parse([
"r\001\000Vt\000\a[objectl\000\000\000\002",
+    array = parse([ "r\001\000Vt\000\a[objectl\000\000\000\
002",
       "S\000\006sillenI\000\000\000 zz" ].join)
+    assert_equal [ 'sillen', 32 ], array
+    assert_equal "[object", array.hessian_type
   end
   def test_array_in_array
-    assert_equal [ 'A list', [ 9, 3 ] ], parse([
"r\001\000Vl\000\000\000\002S\000\006",
+    array = parse([ "r\001\000Vl\000\000\000\002S\000\006&q
uot;,
       "A listVt\000\022[java.lang.Integerl\000\000\000\002I
\000\000\000\t",
       "I\000\000\000\003zzz" ].join)
+    assert_equal [ 'A list', [ 9, 3 ] ], array
+
+    # the outer array was not typed
+    assert !array.respond_to?("hessian_type")
+    # but the inner array was typed
+    assert_equal "[java.lang.Integer",
array[1].hessian_type
   end
   def test_map
-    map = { 'sillen' => 32, 'numbers' => [ 1.1, 1.2, 1.3
] }
-    assert_equal map, parse([
"r\001\000Mt\000\000S\000\anumbersVt\000\a[double",
+    map = parse([ "r\001\000Mt\000\000S\000\anumbersVt\000\
a[double",
       "l\000\000\000\003D?\361\231\231\231\231\231\232D?\36
3333333D?",
-      "\364\314\314\314\314\314\315zS\000\006sillenI\000\000\000
zz" ].join)
-    end
+      "\364\314\314\314\314\314\315zS\000\006sillenI\000\000\000
zz" ].join)
+    assert_equal({ 'sillen' => 32, 'numbers' => [ 1.1,
1.2, 1.3 ] }, map)
+    assert_equal "", map.hessian_type
+  end
 end
Index: lib/hessian.rb
=================================================================
==
--- lib/hessian.rb      (revision 26)
+++ lib/hessian.rb      (working copy)
@@ -10,6 +10,22 @@
     end
   end

+  class HessianTypedArray < Array
+    attr_accessor :hessian_type
+    def initialize(hessian_type, object=[])
+      @hessian_type = hessian_type
+      super(object)
+    end
+  end
+
+  class HessianTypedHash < Hash
+    attr_accessor :hessian_type
+    def initialize(hessian_type, object=nil)
+      @hessian_type = hessian_type
+      super(object)
+    end
+  end
+
   class Binary
     attr :data
     def initialize(data)
@@ -19,8 +35,10 @@

   class HessianException < RuntimeError
     attr_reader :code
-    def initialize(code)
+    attr_reader :details
+    def initialize(code, details)
       @code = code
+      @details = details
     end
   end

@@ -160,22 +178,22 @@
         when 'R': @refs[@data.slice!(0, 4).unpack('N')[0]]
         when 'V'
           # Skip type + type length (2 bytes) if specified.
-          @data.slice!(0, 3 + @data.unpack('an')[1]) if @data[0,1]
== 't'
+          hessian_type = parse_hessian_type if @data[0,1] ==
't'
           # Skip the list length if specified.
           @data.slice!(0, 5) if @data[0,1] == 'l'
-          @refs << (list = [])
+          @refs << (list = hessian_type
? HessianTypedArray.new(hessian_type) : [])
           list << parse_object while @data[0,1] != 'z'
           # Get rid of the 'z'.
           @data.slice!(0, 1)
           list
         when 'M'
           # Skip type + type length (2 bytes) if specified.
-          @data.slice!(0, 3 + @data.unpack('an')[1]) if @data[0,1]
== 't'
-          @refs << (map = {})
+          hessian_type = parse_hessian_type if @data[0,1] ==
't'
+          @refs << (map = hessian_type
? HessianTypedHash.new(hessian_type) : {})
           map[parse_object()] = parse_object while @data[0,1]
!= 'z'
           # Get rid of the 'z'.
           @data.slice!(0, 1)
-          map
+          map
         else
           raise "Invalid type: '#{t}'"
         end
@@ -191,6 +209,13 @@
         @data.slice!(0, 8).each_byte { |b| val += (b & 0xff)
<< o; o -= 8 }
         val
       end
+
+      def parse_hessian_type
+        @data.slice!(0,1) #remove the 't'
+        length = @data.unpack('n')[0]
+        @data.slice!(0,2) # remove the type length
+        hessian_type = @data.slice!(0, length)
+      end

       def raise_exception
         # Skip code description.
@@ -199,7 +224,11 @@
         # Skip message description
         parse_object
         msg = parse_object
-        raise HessianException.new(code), msg
+        # Skip details description
+        parse_object
+        details = parse_object
+
+        raise HessianException.new(code, details), msg
       end
     end
   end
Date: 2008-01-30 19:27
Sender: Larry Karnowski

Oops, I submitted this patch while not logged in!  Just wanted
to let you know who send it in case you needed to ask questions.
Thanks for a great and useful tool!

Larry Karnowski

Attached Files:

Name Description Download
No Files Currently Attached

Changes:

No Changes Have Been Made to This Item