jrjackson 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1d1c4ad52124b5b10d5b17ba157f5d7f51cd4f19
4
- data.tar.gz: 21381583fde4460338bf62312ddc5ae3d2bb484b
3
+ metadata.gz: ff0d3008ed2be467a14efa7ce22f17b798aff14f
4
+ data.tar.gz: 29acde65d94012d051d9ccd24dda9dfb4187cc6b
5
5
  SHA512:
6
- metadata.gz: 05c0daa5a1719b270c8f26269558fafb82002844be119a603970532f88246a104278c268975efcba9ac9afbddf61a235bb0e956ce6feb77695f8bdcee25781f1
7
- data.tar.gz: e2ffaa73398f0a08b4ca39ca50ee5e0dc9ffad2cd9ab9a1d052aa3b48e8cd2f1692e7225591968b7cf7699fc7a722953000f2ba670fa996598a0d4fcdc2e0494
6
+ metadata.gz: 49cad8b054b626adebd9d6a504b4b2d99df08a685f575d034e0ff957c772ee7f6c4bd2ceeec28b6ac41008f6877b54d95470d8de094a961a4dd3ec20bd3c63cd
7
+ data.tar.gz: a2f153ba800e763d4774473beeda5a3861b83303ec1fdd743a5751dc897a97df9796438044f08a45f880f464da67a15b8231d874d5fcbd25af49e30dc88fa026
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+
2
+
1
3
  LICENSE applicable to this library:
2
4
 
3
5
  Apache License 2.0 see http://www.apache.org/licenses/LICENSE-2.0
@@ -14,6 +16,15 @@ There is now a MultiJson adapter added for JrJackson
14
16
 
15
17
  ***
16
18
 
19
+ #### NEWS
20
+
21
+ 26th October 2013 - Added support to serialize arbitary (non JSON datatypes)
22
+ ruby objects. Normally the toJava internal metod is called, but additionally
23
+ to_h, to_hash, to_a and finally to_json are tried. Be aware that the to_json
24
+ method might invoke a new selialization session and impact performance.
25
+
26
+ ***
27
+
17
28
  #### API
18
29
 
19
30
  ```
@@ -76,8 +87,9 @@ generation/serialize
76
87
  json mri generate: 250 12.02 0.00 12.02 ( 12.022)
77
88
  oj mri generate: 250 7.18 0.00 7.18 ( 7.183)
78
89
  json java generate: 250 7.83 0.01 7.84 ( 7.289)
79
- gson generate: 250 5.44 0.00 5.44 ( 5.387)
80
- jackson generate: 250 5.32 0.00 5.32 ( 5.146)
90
+ gson generate: 250 5.04 0.00 5.04 ( 4.995)
91
+ jackson generate: 250 4.94 0.08 5.02 ( 4.811)
92
+
81
93
 
82
94
  parsing/deserialize - after jrjackson parsing profiling
83
95
 
@@ -92,9 +104,6 @@ jackson parse string + bigdecimal: 250 6.27 0.00 6.27 ( 5.973
92
104
  jackson parse symbol keys: 250 5.16 0.00 5.16 ( 4.873)
93
105
  jackson parse symbol + bigdecimal: 250 4.75 0.06 4.81 ( 4.461)
94
106
  jackson parse raw: 250 3.23 0.05 3.28 ( 3.021)
95
- jackson parse raw + bigdecimal: 250 3.06 0.06 3.12 ( 2.681)
107
+ jackson parse raw + bigdecimal: 250 3.06 0.06 3.12 ( 2.639)
96
108
 
97
109
  ```
98
-
99
-
100
-
@@ -4,7 +4,7 @@
4
4
  <groupId>com.jrjackson.jruby</groupId>
5
5
  <artifactId>jrjackson</artifactId>
6
6
  <name>jrjackson</name>
7
- <version>1.2.3</version>
7
+ <version>1.2.4</version>
8
8
  <url>http://maven.apache.org</url>
9
9
  <build>
10
10
  <plugins>
@@ -3,7 +3,8 @@ unless RUBY_PLATFORM =~ /java/
3
3
  exit 255
4
4
  end
5
5
 
6
- require_relative "jars/jrjackson-1.2.3.jar"
6
+ require_relative "jars/jrjackson-1.2.4.jar"
7
+ # require_relative "linked/jrjackson-1.2.4.jar"
7
8
 
8
9
  require 'com/jrjackson/jr_jackson'
9
10
 
@@ -1,3 +1,3 @@
1
1
  module JrJackson
2
- VERSION = '0.2.2'
2
+ VERSION = '0.2.3'
3
3
  end
data/pom.xml CHANGED
@@ -5,7 +5,7 @@
5
5
  <groupId>com.jrjackson.jruby</groupId>
6
6
  <artifactId>jrjackson</artifactId>
7
7
  <packaging>jar</packaging>
8
- <version>1.2.3</version>
8
+ <version>1.2.4</version>
9
9
  <name>jrjackson</name>
10
10
  <url>http://maven.apache.org</url>
11
11
 
@@ -144,9 +144,14 @@ public class JrJacksonRaw extends RubyObject {
144
144
 
145
145
  // serialize
146
146
  @JRubyMethod(module = true, name = {"generate", "dump"}, required = 1)
147
- public static IRubyObject generate(ThreadContext context, IRubyObject self, IRubyObject arg) {
147
+ public static IRubyObject generate(ThreadContext context, IRubyObject self, IRubyObject arg)
148
+ throws IOException, JsonProcessingException
149
+ {
148
150
  Ruby ruby = context.getRuntime();
149
151
  Object obj = arg.toJava(Object.class);
152
+ // String s = mappers.get("raw").writeValueAsString(obj);
153
+ // return RubyUtils.rubyString(ruby, s);
154
+
150
155
  try {
151
156
  String s = mappers.get("raw").writeValueAsString(obj);
152
157
  return RubyUtils.rubyString(ruby, s);
@@ -1,8 +1,9 @@
1
1
  package com.jrjackson;
2
2
 
3
3
  import org.jruby.Ruby;
4
- import org.jruby.RubyClass;
5
4
  import org.jruby.RubyModule;
5
+ import org.jruby.RubyClass;
6
+ import org.jruby.RubyObject;
6
7
  import org.jruby.runtime.ObjectAllocator;
7
8
  import org.jruby.runtime.builtin.IRubyObject;
8
9
  import org.jruby.runtime.load.BasicLibraryService;
@@ -0,0 +1,116 @@
1
+ package com.jrjackson;
2
+
3
+ import java.io.IOException;
4
+ import java.lang.reflect.Type;
5
+ import java.util.*;
6
+
7
+ import com.fasterxml.jackson.core.*;
8
+
9
+ import com.fasterxml.jackson.databind.ser.std.StdSerializer;
10
+ import com.fasterxml.jackson.databind.JsonSerializer;
11
+ import com.fasterxml.jackson.databind.SerializerProvider;
12
+
13
+ import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
14
+
15
+ import org.jruby.*;
16
+ import org.jruby.runtime.ThreadContext;
17
+ import org.jruby.internal.runtime.methods.DynamicMethod;
18
+
19
+ public class RubyAnySerializer extends StdSerializer<RubyObject>
20
+ {
21
+ /**
22
+ * Singleton instance to use.
23
+ */
24
+ public static final RubyAnySerializer instance = new RubyAnySerializer();
25
+ private static HashMap<Class, Class> class_maps = new HashMap<Class, Class>();
26
+
27
+ static {
28
+ class_maps.put(RubyBoolean.class, Boolean.class);
29
+ }
30
+
31
+ public RubyAnySerializer() { super(RubyObject.class); }
32
+
33
+ private Class<?> rubyJavaClassLookup(Class target)
34
+ {
35
+ Class<?> val = class_maps.get(target);
36
+ if (val == null) {
37
+ return Object.class;
38
+ }
39
+ return val;
40
+ }
41
+
42
+ private void serializeUnknownRubyObject(RubyObject rubyObject, JsonGenerator jgen, SerializerProvider provider)
43
+ throws IOException, JsonGenerationException
44
+ {
45
+ ThreadContext ctx = rubyObject.getRuntime().getCurrentContext();
46
+ RubyClass meta = rubyObject.getMetaClass();
47
+ DynamicMethod method = meta.searchMethod("to_h");
48
+ if (!method.isUndefined()) {
49
+ RubyObject obj = (RubyObject)method.call(ctx, rubyObject, meta, "to_h");
50
+ provider.findTypedValueSerializer(Map.class, true, null).serialize(obj, jgen, provider);
51
+ return;
52
+ }
53
+
54
+ method = meta.searchMethod("to_hash");
55
+ if (!method.isUndefined()) {
56
+ RubyObject obj = (RubyObject)method.call(ctx, rubyObject, meta, "to_hash");
57
+ provider.findTypedValueSerializer(Map.class, true, null).serialize(obj, jgen, provider);
58
+ return;
59
+ }
60
+
61
+ method = meta.searchMethod("to_a");
62
+ if (!method.isUndefined()) {
63
+ RubyObject obj = (RubyObject)method.call(ctx, rubyObject, meta, "to_a");
64
+ provider.findTypedValueSerializer(List.class, true, null).serialize(obj, jgen, provider);
65
+ return;
66
+ }
67
+
68
+ method = meta.searchMethod("to_json");
69
+ if (!method.isUndefined()) {
70
+ RubyObject obj = (RubyObject)method.call(ctx, rubyObject, meta, "to_json");
71
+ if (obj instanceof RubyString) {
72
+ jgen.writeRawValue(obj.toString());
73
+ } else {
74
+ provider.defaultSerializeValue(obj, jgen);
75
+ }
76
+ return;
77
+ }
78
+ throw new JsonGenerationException("Cannot find Serializer for class: " + rubyObject.getClass().getName());
79
+ }
80
+
81
+ @Override
82
+ public void serialize(RubyObject value, JsonGenerator jgen, SerializerProvider provider)
83
+ throws IOException, JsonGenerationException
84
+ {
85
+ if (value instanceof RubySymbol || value instanceof RubyString) {
86
+ jgen.writeString(value.toString());
87
+ } else if (value instanceof RubyHash) {
88
+ provider.findTypedValueSerializer(Map.class, true, null).serialize(value, jgen, provider);
89
+ } else if (value instanceof RubyArray) {
90
+ provider.findTypedValueSerializer(List.class, true, null).serialize(value, jgen, provider);
91
+ } else {
92
+ Object val = value.toJava(rubyJavaClassLookup(value.getClass()));
93
+ if ( val instanceof RubyObject) {
94
+ serializeUnknownRubyObject((RubyObject)val, jgen, provider);
95
+ } else {
96
+ provider.defaultSerializeValue(val, jgen);
97
+ }
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Default implementation will write type prefix, call regular serialization
103
+ * method (since assumption is that value itself does not need JSON
104
+ * Array or Object start/end markers), and then write type suffix.
105
+ * This should work for most cases; some sub-classes may want to
106
+ * change this behavior.
107
+ */
108
+ @Override
109
+ public void serializeWithType(RubyObject value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer)
110
+ throws IOException, JsonGenerationException
111
+ {
112
+ typeSer.writeTypePrefixForScalar(value, jgen);
113
+ serialize(value, jgen, provider);
114
+ typeSer.writeTypeSuffixForScalar(value, jgen);
115
+ }
116
+ }
@@ -1,14 +1,16 @@
1
1
  package com.jrjackson;
2
2
 
3
3
  import java.util.*;
4
+ import java.text.SimpleDateFormat;
4
5
 
5
6
  import org.jruby.*;
6
- import org.jruby.util.RubyDateFormat;
7
+ // import org.jruby.util.RubyDateFormat;
7
8
 
8
9
  import com.fasterxml.jackson.databind.ObjectMapper;
9
10
  import com.fasterxml.jackson.databind.module.SimpleModule;
11
+ import com.fasterxml.jackson.databind.SerializationFeature;
10
12
  import com.fasterxml.jackson.core.util.VersionUtil;
11
- import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
13
+ import com.fasterxml.jackson.databind.ser.std.DateSerializer;
12
14
  import com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer;
13
15
  import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
14
16
 
@@ -43,21 +45,22 @@ public class RubyJacksonModule extends SimpleModule
43
45
  asStr()
44
46
  );
45
47
  }
46
- mapper.setDateFormat(new RubyDateFormat("yyyy-MM-dd HH:mm:ss z", Locale.US, true));
48
+ mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
49
+ mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"));
47
50
  return mapper;
48
51
  }
49
52
 
50
53
  public static SimpleModule asRaw()
51
54
  {
52
55
  return new RubyJacksonModule().addSerializer(
53
- RubySymbol.class, ToStringSerializer.instance
56
+ RubyObject.class, RubyAnySerializer.instance
54
57
  );
55
58
  }
56
59
 
57
60
  public static SimpleModule asSym()
58
61
  {
59
62
  return new RubyJacksonModule().addSerializer(
60
- RubySymbol.class, ToStringSerializer.instance
63
+ RubyObject.class, RubyAnySerializer.instance
61
64
  ).addDeserializer(
62
65
  Object.class, new RubyObjectDeserializer().setSymbolStrategy()
63
66
  );
@@ -66,7 +69,7 @@ public class RubyJacksonModule extends SimpleModule
66
69
  public static SimpleModule asStr()
67
70
  {
68
71
  return new RubyJacksonModule().addSerializer(
69
- RubySymbol.class, ToStringSerializer.instance
72
+ RubyObject.class, RubyAnySerializer.instance
70
73
  ).addDeserializer(
71
74
  Object.class, new RubyObjectDeserializer().setStringStrategy()
72
75
  );
@@ -26,8 +26,6 @@ public class RubyObjectDeserializer
26
26
 
27
27
  protected final static Ruby __ruby__ = Ruby.getGlobalRuntime();
28
28
 
29
- private static final HashMap<String, RubyKeyConverter> converters = new HashMap<String, RubyKeyConverter>(3);
30
-
31
29
  private RubyKeyConverter converter;
32
30
 
33
31
  public RubyObjectDeserializer() {
@@ -74,7 +72,8 @@ public class RubyObjectDeserializer
74
72
  return RubyUtils.rubyObject(__ruby__, jp.getEmbeddedObject());
75
73
 
76
74
  case VALUE_STRING:
77
- return RubyUtils.rubyString(__ruby__, jp.getText().getBytes());
75
+ // return RubyUtils.rubyString(__ruby__, jp.getText().getBytes("UTF-8"));
76
+ return RubyUtils.rubyString(__ruby__, jp.getText());
78
77
 
79
78
  case VALUE_NUMBER_INT:
80
79
  /* [JACKSON-100]: caller may want to get all integral values
@@ -90,7 +89,6 @@ public class RubyObjectDeserializer
90
89
  return RubyUtils.rubyBigDecimal(__ruby__, jp.getDecimalValue());
91
90
  }
92
91
  return RubyUtils.rubyFloat(__ruby__, jp.getDoubleValue());
93
- // return RubyUtils.rubyFloat(__ruby__, jp.getText());
94
92
 
95
93
  case VALUE_TRUE:
96
94
  return __ruby__.newBoolean(Boolean.TRUE);
@@ -1,5 +1,9 @@
1
+ # encoding: UTF-8
2
+
1
3
  $LOAD_PATH << File.expand_path('../../lib', __FILE__)
2
4
 
5
+ require "java"
6
+
3
7
  require 'test/unit'
4
8
  require 'thread'
5
9
  require 'bigdecimal'
@@ -7,6 +11,38 @@ require 'jrjackson'
7
11
 
8
12
  class JrJacksonTest < Test::Unit::TestCase
9
13
 
14
+ class CustomToH
15
+ attr_accessor :one, :two, :six
16
+ def initialize(a,b,c)
17
+ @one, @two, @six = a,b,c
18
+ end
19
+ def to_h
20
+ {'one' => one, 'two' => two, 'six' => six}
21
+ end
22
+ end
23
+
24
+ class CustomToHash
25
+ attr_accessor :one, :two, :six
26
+ def initialize(a,b,c)
27
+ @one, @two, @six = a,b,c
28
+ end
29
+ def to_hash
30
+ {'one' => one, 'two' => two, 'six' => six}
31
+ end
32
+ end
33
+
34
+ class CustomToJson
35
+ attr_accessor :one, :two, :six
36
+ def initialize(a,b,c)
37
+ @one, @two, @six = a,b,c
38
+ end
39
+ def to_json
40
+ %Q|{"one":#{one},"two":#{two},"six":#{six}}|
41
+ end
42
+ end
43
+
44
+ CustomStruct = Struct.new(:one, :two, :six)
45
+
10
46
  def test_threading
11
47
  q1, q2, q3 = Queue.new, Queue.new, Queue.new
12
48
 
@@ -28,10 +64,30 @@ class JrJacksonTest < Test::Unit::TestCase
28
64
  assert a3.values.all? {|v| v.is_a?(Float)}, "Expected all values to be Float"
29
65
  end
30
66
 
31
- def test_serialize_symbols_as_values
32
- source = {"first" => :first_symbol, "second" => {"inner" => :inner_symbol}}
33
- expected = {:first => "first_symbol", :second => {:inner => "inner_symbol"}}
34
- actual = JrJackson::Json.load(JrJackson::Json.dump(source), :symbolize_keys => true)
67
+ def test_deserialize_JSON_with_UTF8_characters
68
+ json_string = JrJackson::Json.dump({"utf8" => "żółć"})
69
+ expected = {utf8: "żółć"}
70
+ actual = JrJackson::Json.load(json_string, :symbolize_keys => true)
71
+ assert_equal expected, actual
72
+ end
73
+
74
+ def test_serialize_non_json_datatypes_as_values
75
+ dt = Time.now
76
+ co1 = CustomToH.new("uno", :two, 6.0)
77
+ co2 = CustomToHash.new("uno", :two, 6.0)
78
+ co3 = CustomToJson.new(1.0, 2, 6.0)
79
+ co4 = CustomStruct.new(1, 2, 6)
80
+ source = {"sym" => :a_symbol, "dt" => dt, "co1" => co1, "co2" => co2, "co3" => co3, "co4" => co4}
81
+ json_string = JrJackson::Json.dump(source)
82
+ expected = {
83
+ :sym => "a_symbol",
84
+ :dt => dt.strftime("%F %T %Z"),
85
+ :co1 => {:one => "uno", :two => "two", :six => 6.0 },
86
+ :co2 => {:one => "uno", :two => "two", :six => 6.0 },
87
+ :co3 => {:one => 1.0, :two => 2.0, :six => 6.0 },
88
+ :co4 => [1, 2, 6],
89
+ }
90
+ actual = JrJackson::Json.load(json_string, :symbolize_keys => true)
35
91
  assert_equal expected, actual
36
92
  end
37
93
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jrjackson
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Guy Boertje
@@ -59,7 +59,7 @@ files:
59
59
  - dependency-reduced-pom.xml
60
60
  - jrjackson.gemspec
61
61
  - lib/jrjackson.rb
62
- - lib/jrjackson/jars/jrjackson-1.2.3.jar
62
+ - lib/jrjackson/jars/jrjackson-1.2.4.jar
63
63
  - lib/jrjackson/jrjackson.rb
64
64
  - lib/jrjackson/version.rb
65
65
  - lib/require_relative_patch.rb
@@ -69,6 +69,7 @@ files:
69
69
  - src/main/java/com/jrjackson/JrJacksonRaw.java
70
70
  - src/main/java/com/jrjackson/JrJacksonService.java
71
71
  - src/main/java/com/jrjackson/ParseError.java
72
+ - src/main/java/com/jrjackson/RubyAnySerializer.java
72
73
  - src/main/java/com/jrjackson/RubyJacksonModule.java
73
74
  - src/main/java/com/jrjackson/RubyKeyConverter.java
74
75
  - src/main/java/com/jrjackson/RubyObjectDeserializer.java