jrjackson 0.2.6 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/dependency-reduced-pom.xml +14 -5
- data/lib/jrjackson/build_info.rb +1 -1
- data/lib/jrjackson/jars/{jrjackson-1.2.8.jar → jrjackson-1.2.9.jar} +0 -0
- data/lib/jrjackson/jrjackson.rb +2 -2
- data/pom.xml +4 -4
- data/src/main/java/com/jrjackson/JrJacksonRaw.java +89 -101
- data/src/main/java/com/jrjackson/JrJacksonService.java +10 -11
- data/src/main/java/com/jrjackson/ParseError.java +5 -4
- data/src/main/java/com/jrjackson/RubyAnySerializer.java +97 -90
- data/src/main/java/com/jrjackson/RubyJacksonModule.java +49 -59
- data/src/main/java/com/jrjackson/RubyKeyConverter.java +3 -3
- data/src/main/java/com/jrjackson/RubyObjectDeserializer.java +158 -155
- data/src/main/java/com/jrjackson/RubyStringConverter.java +6 -5
- data/src/main/java/com/jrjackson/RubySymbolConverter.java +5 -5
- data/src/main/java/com/jrjackson/RubyUtils.java +58 -76
- data/test/jrjackson_test.rb +12 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9cfaa7407bdd2661d42803ddeb31cd08cb5f64cd
|
4
|
+
data.tar.gz: 12c5ff2193c1b189cecbea58972a2f7b6aefb622
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6c5d5db9a8874e9f19297de099a048c8913a8ad6df1d0e7758bd0dcfd9ef57a07dae2bd8db4c22b5dc077ff8745667ce23854c63e745cddb65b05c5e2f940db
|
7
|
+
data.tar.gz: 677855c6cd7ae971d70b3865092483b8a55cf136ae07fed3e166440dd8ee843d562db67e72efa4a09513198c0a9c95c6f468e57ad840fbd9d77d5009e7d365bc
|
data/dependency-reduced-pom.xml
CHANGED
@@ -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.
|
7
|
+
<version>1.2.9</version>
|
8
8
|
<url>http://maven.apache.org</url>
|
9
9
|
<build>
|
10
10
|
<plugins>
|
@@ -24,8 +24,7 @@
|
|
24
24
|
<artifactId>maven-surefire-plugin</artifactId>
|
25
25
|
<version>2.16</version>
|
26
26
|
<configuration>
|
27
|
-
<
|
28
|
-
<threadCount>10</threadCount>
|
27
|
+
<skipTests>true</skipTests>
|
29
28
|
</configuration>
|
30
29
|
</plugin>
|
31
30
|
<plugin>
|
@@ -67,8 +66,18 @@
|
|
67
66
|
<dependency>
|
68
67
|
<groupId>org.jruby</groupId>
|
69
68
|
<artifactId>jruby</artifactId>
|
70
|
-
<version>1.7.
|
71
|
-
<scope>
|
69
|
+
<version>1.7.11</version>
|
70
|
+
<scope>provided</scope>
|
71
|
+
<exclusions>
|
72
|
+
<exclusion>
|
73
|
+
<artifactId>jruby-core</artifactId>
|
74
|
+
<groupId>org.jruby</groupId>
|
75
|
+
</exclusion>
|
76
|
+
<exclusion>
|
77
|
+
<artifactId>jruby-stdlib</artifactId>
|
78
|
+
<groupId>org.jruby</groupId>
|
79
|
+
</exclusion>
|
80
|
+
</exclusions>
|
72
81
|
</dependency>
|
73
82
|
</dependencies>
|
74
83
|
<properties>
|
data/lib/jrjackson/build_info.rb
CHANGED
Binary file
|
data/lib/jrjackson/jrjackson.rb
CHANGED
@@ -3,8 +3,8 @@ unless RUBY_PLATFORM =~ /java/
|
|
3
3
|
exit 255
|
4
4
|
end
|
5
5
|
|
6
|
-
require_relative "jars/jrjackson-1.2.
|
7
|
-
# require_relative "linked/jrjackson-1.2.
|
6
|
+
require_relative "jars/jrjackson-1.2.9.jar"
|
7
|
+
# require_relative "linked/jrjackson-1.2.9.jar"
|
8
8
|
|
9
9
|
require 'com/jrjackson/jr_jackson'
|
10
10
|
|
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.
|
8
|
+
<version>1.2.9</version>
|
9
9
|
<name>jrjackson</name>
|
10
10
|
<url>http://maven.apache.org</url>
|
11
11
|
|
@@ -23,7 +23,8 @@
|
|
23
23
|
<dependency>
|
24
24
|
<groupId>org.jruby</groupId>
|
25
25
|
<artifactId>jruby</artifactId>
|
26
|
-
<version>1.7.
|
26
|
+
<version>1.7.11</version>
|
27
|
+
<scope>provided</scope>
|
27
28
|
</dependency>
|
28
29
|
<dependency>
|
29
30
|
<groupId>com.fasterxml.jackson.core</groupId>
|
@@ -66,8 +67,7 @@
|
|
66
67
|
<artifactId>maven-surefire-plugin</artifactId>
|
67
68
|
<version>2.16</version>
|
68
69
|
<configuration>
|
69
|
-
<
|
70
|
-
<threadCount>10</threadCount>
|
70
|
+
<skipTests>true</skipTests>
|
71
71
|
</configuration>
|
72
72
|
</plugin>
|
73
73
|
<plugin>
|
@@ -23,117 +23,105 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
|
23
23
|
@JRubyModule(name = "JrJacksonRaw")
|
24
24
|
public class JrJacksonRaw extends RubyObject {
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
}
|
29
|
-
|
30
|
-
private static boolean flagged(RubyHash opts, RubySymbol key) {
|
31
|
-
Object val = opts.get(key);
|
32
|
-
if (val == null) {
|
33
|
-
return false;
|
26
|
+
public JrJacksonRaw(Ruby ruby, RubyClass metaclass) {
|
27
|
+
super(ruby, metaclass);
|
34
28
|
}
|
35
|
-
return (Boolean) val;
|
36
|
-
}
|
37
|
-
|
38
|
-
// deserialize
|
39
|
-
@JRubyMethod(module = true, name = {"parse", "load"}, required = 2)
|
40
|
-
public static IRubyObject parse(ThreadContext context, IRubyObject self, IRubyObject arg, IRubyObject opts)
|
41
|
-
throws IOException
|
42
|
-
{
|
43
|
-
RubyHash options = null;
|
44
|
-
ObjectMapper local = null;
|
45
|
-
Ruby _ruby = context.getRuntime();
|
46
29
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
local = RubyJacksonModule.mappedAs("raw", _ruby);
|
54
|
-
}
|
55
|
-
if (local == null) {
|
56
|
-
local = RubyJacksonModule.mappedAs("str", _ruby);
|
57
|
-
}
|
58
|
-
if (flagged(options, RubyUtils.rubySymbol(_ruby, "use_bigdecimal"))) {
|
59
|
-
local.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
|
60
|
-
}
|
61
|
-
else {
|
62
|
-
local.disable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
|
63
|
-
}
|
64
|
-
}
|
65
|
-
else {
|
66
|
-
local = RubyJacksonModule.mappedAs("str", _ruby);
|
30
|
+
private static boolean flagged(RubyHash opts, RubySymbol key) {
|
31
|
+
Object val = opts.get(key);
|
32
|
+
if (val == null) {
|
33
|
+
return false;
|
34
|
+
}
|
35
|
+
return (Boolean) val;
|
67
36
|
}
|
68
|
-
return _parse(context, arg, local);
|
69
|
-
}
|
70
|
-
|
71
|
-
@JRubyMethod(module = true, name = {"parse_raw", "load_raw"}, required = 1)
|
72
|
-
public static IRubyObject parse_raw(ThreadContext context, IRubyObject self, IRubyObject arg)
|
73
|
-
throws IOException
|
74
|
-
{
|
75
|
-
ObjectMapper mapper = RubyJacksonModule.mappedAs("raw", context.getRuntime());
|
76
|
-
return _parse(context, arg, mapper);
|
77
|
-
}
|
78
|
-
|
79
|
-
@JRubyMethod(module = true, name = {"parse_sym", "load_sym"}, required = 1)
|
80
|
-
public static IRubyObject parse_sym(ThreadContext context, IRubyObject self, IRubyObject arg)
|
81
|
-
throws IOException
|
82
|
-
{
|
83
|
-
ObjectMapper mapper = RubyJacksonModule.mappedAs("sym", context.getRuntime());
|
84
|
-
return _parse(context, arg, mapper);
|
85
|
-
}
|
86
37
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
38
|
+
// deserialize
|
39
|
+
@JRubyMethod(module = true, name = {"parse", "load"}, required = 2)
|
40
|
+
public static IRubyObject parse(ThreadContext context, IRubyObject self, IRubyObject arg, IRubyObject opts)
|
41
|
+
throws IOException {
|
42
|
+
RubyHash options = null;
|
43
|
+
ObjectMapper local = null;
|
44
|
+
Ruby _ruby = context.getRuntime();
|
94
45
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
46
|
+
if (opts != context.nil) {
|
47
|
+
options = opts.convertToHash();
|
48
|
+
if (flagged(options, RubyUtils.rubySymbol(_ruby, "symbolize_keys"))) {
|
49
|
+
local = RubyJacksonModule.mappedAs("sym", _ruby);
|
50
|
+
}
|
51
|
+
if (flagged(options, RubyUtils.rubySymbol(_ruby, "raw"))) {
|
52
|
+
local = RubyJacksonModule.mappedAs("raw", _ruby);
|
53
|
+
}
|
54
|
+
if (local == null) {
|
55
|
+
local = RubyJacksonModule.mappedAs("str", _ruby);
|
56
|
+
}
|
57
|
+
if (flagged(options, RubyUtils.rubySymbol(_ruby, "use_bigdecimal"))) {
|
58
|
+
local.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
|
59
|
+
} else {
|
60
|
+
local.disable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
|
61
|
+
}
|
62
|
+
} else {
|
63
|
+
local = RubyJacksonModule.mappedAs("str", _ruby);
|
64
|
+
}
|
65
|
+
return _parse(context, arg, local);
|
111
66
|
}
|
112
|
-
|
113
|
-
|
67
|
+
|
68
|
+
@JRubyMethod(module = true, name = {"parse_raw", "load_raw"}, required = 1)
|
69
|
+
public static IRubyObject parse_raw(ThreadContext context, IRubyObject self, IRubyObject arg)
|
70
|
+
throws IOException {
|
71
|
+
ObjectMapper mapper = RubyJacksonModule.mappedAs("raw", context.getRuntime());
|
72
|
+
return _parse(context, arg, mapper);
|
114
73
|
}
|
115
|
-
|
116
|
-
|
74
|
+
|
75
|
+
@JRubyMethod(module = true, name = {"parse_sym", "load_sym"}, required = 1)
|
76
|
+
public static IRubyObject parse_sym(ThreadContext context, IRubyObject self, IRubyObject arg)
|
77
|
+
throws IOException {
|
78
|
+
ObjectMapper mapper = RubyJacksonModule.mappedAs("sym", context.getRuntime());
|
79
|
+
return _parse(context, arg, mapper);
|
117
80
|
}
|
118
|
-
}
|
119
81
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
Ruby _ruby = context.getRuntime();
|
126
|
-
Object obj = arg.toJava(Object.class);
|
127
|
-
try {
|
128
|
-
ObjectMapper mapper = RubyJacksonModule.mappedAs("raw", _ruby);
|
129
|
-
String s = mapper.writeValueAsString(obj);
|
130
|
-
return RubyUtils.rubyString(_ruby, s);
|
82
|
+
@JRubyMethod(module = true, name = {"parse_str", "load_str"}, required = 1)
|
83
|
+
public static IRubyObject parse_str(ThreadContext context, IRubyObject self, IRubyObject arg)
|
84
|
+
throws IOException {
|
85
|
+
ObjectMapper mapper = RubyJacksonModule.mappedAs("str", context.getRuntime());
|
86
|
+
return _parse(context, arg, mapper);
|
131
87
|
}
|
132
|
-
|
133
|
-
|
88
|
+
|
89
|
+
private static IRubyObject _parse(ThreadContext context, IRubyObject arg, ObjectMapper mapper)
|
90
|
+
throws IOException {
|
91
|
+
Ruby ruby = context.getRuntime();
|
92
|
+
try {
|
93
|
+
Object o;
|
94
|
+
if (arg instanceof RubyString) {
|
95
|
+
o = mapper.readValue(
|
96
|
+
((RubyString) arg).getBytes(), Object.class
|
97
|
+
);
|
98
|
+
} else {
|
99
|
+
// must be an IO object then
|
100
|
+
IRubyObject stream = IOJavaAddons.AnyIO.any_to_inputstream(context, arg);
|
101
|
+
o = mapper.readValue((InputStream) stream.toJava(InputStream.class), Object.class);
|
102
|
+
}
|
103
|
+
return RubyUtils.rubyObject(ruby, o);
|
104
|
+
} catch (JsonProcessingException e) {
|
105
|
+
throw ParseError.newParseError(ruby, e.getLocalizedMessage());
|
106
|
+
} catch (IOException e) {
|
107
|
+
throw ruby.newIOError(e.getLocalizedMessage());
|
108
|
+
}
|
134
109
|
}
|
135
|
-
|
136
|
-
|
110
|
+
|
111
|
+
// serialize
|
112
|
+
@JRubyMethod(module = true, name = {"generate", "dump"}, required = 1)
|
113
|
+
public static IRubyObject generate(ThreadContext context, IRubyObject self, IRubyObject arg)
|
114
|
+
throws IOException, JsonProcessingException {
|
115
|
+
Ruby _ruby = context.getRuntime();
|
116
|
+
Object obj = arg.toJava(Object.class);
|
117
|
+
try {
|
118
|
+
ObjectMapper mapper = RubyJacksonModule.mappedAs("raw", _ruby);
|
119
|
+
String s = mapper.writeValueAsString(obj);
|
120
|
+
return RubyUtils.rubyString(_ruby, s);
|
121
|
+
} catch (JsonProcessingException e) {
|
122
|
+
throw ParseError.newParseError(_ruby, e.getLocalizedMessage());
|
123
|
+
} catch (IOException e) {
|
124
|
+
throw _ruby.newIOError(e.getLocalizedMessage());
|
125
|
+
}
|
137
126
|
}
|
138
|
-
}
|
139
127
|
}
|
@@ -3,22 +3,21 @@ package com.jrjackson;
|
|
3
3
|
import org.jruby.Ruby;
|
4
4
|
import org.jruby.RubyModule;
|
5
5
|
import org.jruby.RubyClass;
|
6
|
-
import org.jruby.RubyObject;
|
7
|
-
import org.jruby.runtime.ObjectAllocator;
|
8
|
-
import org.jruby.runtime.builtin.IRubyObject;
|
9
6
|
import org.jruby.runtime.load.BasicLibraryService;
|
10
7
|
|
11
8
|
import java.io.IOException;
|
12
9
|
|
13
10
|
public class JrJacksonService implements BasicLibraryService {
|
14
|
-
public boolean basicLoad(final Ruby ruby) throws IOException {
|
15
|
-
RubyModule jr_jackson = ruby.defineModule("JrJackson");
|
16
11
|
|
17
|
-
|
18
|
-
|
12
|
+
@Override
|
13
|
+
public boolean basicLoad(final Ruby ruby) throws IOException {
|
14
|
+
RubyModule jr_jackson = ruby.defineModule("JrJackson");
|
19
15
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
16
|
+
RubyModule jr_jackson_raw = ruby.defineModuleUnder("Raw", jr_jackson);
|
17
|
+
jr_jackson_raw.defineAnnotatedMethods(JrJacksonRaw.class);
|
18
|
+
|
19
|
+
RubyClass runtimeError = ruby.getRuntimeError();
|
20
|
+
RubyClass parseError = jr_jackson.defineClassUnder("ParseError", runtimeError, runtimeError.getAllocator());
|
21
|
+
return true;
|
22
|
+
}
|
24
23
|
}
|
@@ -8,8 +8,9 @@ import org.jruby.exceptions.RaiseException;
|
|
8
8
|
|
9
9
|
@JRubyClass(name = "JrJackson::ParseError", parent = "RuntimeError")
|
10
10
|
public class ParseError {
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
|
12
|
+
public static RaiseException newParseError(Ruby ruby, String message) {
|
13
|
+
RubyClass errorClass = ruby.getModule("JrJackson").getClass("ParseError");
|
14
|
+
return new RaiseException(RubyException.newException(ruby, errorClass, message), true);
|
15
|
+
}
|
15
16
|
}
|
@@ -1,13 +1,11 @@
|
|
1
1
|
package com.jrjackson;
|
2
2
|
|
3
3
|
import java.io.IOException;
|
4
|
-
import java.lang.reflect.Type;
|
5
4
|
import java.util.*;
|
6
5
|
|
7
6
|
import com.fasterxml.jackson.core.*;
|
8
7
|
|
9
8
|
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
10
|
-
import com.fasterxml.jackson.databind.JsonSerializer;
|
11
9
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
12
10
|
|
13
11
|
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
|
@@ -16,101 +14,110 @@ import org.jruby.*;
|
|
16
14
|
import org.jruby.runtime.ThreadContext;
|
17
15
|
import org.jruby.internal.runtime.methods.DynamicMethod;
|
18
16
|
|
19
|
-
public class RubyAnySerializer extends StdSerializer<RubyObject>
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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;
|
17
|
+
public class RubyAnySerializer extends StdSerializer<RubyObject> {
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Singleton instance to use.
|
21
|
+
*/
|
22
|
+
public static final RubyAnySerializer instance = new RubyAnySerializer();
|
23
|
+
private static final HashMap<Class, Class> class_maps = new HashMap<Class, Class>();
|
24
|
+
|
25
|
+
static {
|
26
|
+
class_maps.put(RubyBoolean.class, Boolean.class);
|
38
27
|
}
|
39
|
-
|
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;
|
28
|
+
|
29
|
+
public RubyAnySerializer() {
|
30
|
+
super(RubyObject.class);
|
52
31
|
}
|
53
32
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
33
|
+
private Class<?> rubyJavaClassLookup(Class target) {
|
34
|
+
Class<?> val = class_maps.get(target);
|
35
|
+
if (val == null) {
|
36
|
+
return Object.class;
|
37
|
+
}
|
38
|
+
return val;
|
59
39
|
}
|
60
40
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
41
|
+
private void serializeUnknownRubyObject(RubyObject rubyObject, JsonGenerator jgen, SerializerProvider provider)
|
42
|
+
throws IOException, JsonGenerationException {
|
43
|
+
ThreadContext ctx = rubyObject.getRuntime().getCurrentContext();
|
44
|
+
RubyClass meta = rubyObject.getMetaClass();
|
45
|
+
|
46
|
+
DynamicMethod method = meta.searchMethod("to_time");
|
47
|
+
if (!method.isUndefined()) {
|
48
|
+
RubyObject obj = (RubyObject) method.call(ctx, rubyObject, meta, "to_time");
|
49
|
+
provider.defaultSerializeValue(obj, jgen);
|
50
|
+
return;
|
51
|
+
}
|
52
|
+
|
53
|
+
method = meta.searchMethod("to_h");
|
54
|
+
if (!method.isUndefined()) {
|
55
|
+
RubyObject obj = (RubyObject) method.call(ctx, rubyObject, meta, "to_h");
|
56
|
+
provider.findTypedValueSerializer(Map.class, true, null).serialize(obj, jgen, provider);
|
57
|
+
return;
|
58
|
+
}
|
59
|
+
|
60
|
+
method = meta.searchMethod("to_hash");
|
61
|
+
if (!method.isUndefined()) {
|
62
|
+
RubyObject obj = (RubyObject) method.call(ctx, rubyObject, meta, "to_hash");
|
63
|
+
provider.findTypedValueSerializer(Map.class, true, null).serialize(obj, jgen, provider);
|
64
|
+
return;
|
65
|
+
}
|
66
|
+
|
67
|
+
method = meta.searchMethod("to_a");
|
68
|
+
if (!method.isUndefined()) {
|
69
|
+
RubyObject obj = (RubyObject) method.call(ctx, rubyObject, meta, "to_a");
|
70
|
+
provider.findTypedValueSerializer(List.class, true, null).serialize(obj, jgen, provider);
|
71
|
+
return;
|
72
|
+
}
|
73
|
+
|
74
|
+
method = meta.searchMethod("to_json");
|
75
|
+
if (!method.isUndefined()) {
|
76
|
+
RubyObject obj = (RubyObject) method.call(ctx, rubyObject, meta, "to_json");
|
77
|
+
if (obj instanceof RubyString) {
|
78
|
+
jgen.writeRawValue(obj.toString());
|
79
|
+
} else {
|
80
|
+
provider.defaultSerializeValue(obj, jgen);
|
81
|
+
}
|
82
|
+
return;
|
83
|
+
}
|
84
|
+
throw new JsonGenerationException("Cannot find Serializer for class: " + rubyObject.getClass().getName());
|
66
85
|
}
|
67
86
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
87
|
+
@Override
|
88
|
+
public void serialize(RubyObject value, JsonGenerator jgen, SerializerProvider provider)
|
89
|
+
throws IOException, JsonGenerationException {
|
90
|
+
if (value instanceof RubySymbol || value instanceof RubyString) {
|
91
|
+
jgen.writeString(value.toString());
|
92
|
+
} else if (value instanceof RubyHash) {
|
93
|
+
provider.findTypedValueSerializer(Map.class, true, null).serialize(value, jgen, provider);
|
94
|
+
} else if (value instanceof RubyArray) {
|
95
|
+
provider.findTypedValueSerializer(List.class, true, null).serialize(value, jgen, provider);
|
96
|
+
} else {
|
97
|
+
Object val = value.toJava(rubyJavaClassLookup(value.getClass()));
|
98
|
+
if (val instanceof RubyObject) {
|
99
|
+
serializeUnknownRubyObject((RubyObject) val, jgen, provider);
|
100
|
+
} else {
|
101
|
+
provider.defaultSerializeValue(val, jgen);
|
102
|
+
}
|
103
|
+
}
|
77
104
|
}
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
} else {
|
96
|
-
provider.defaultSerializeValue(val, jgen);
|
97
|
-
}
|
105
|
+
|
106
|
+
/**
|
107
|
+
* Default implementation will write type prefix, call regular serialization method (since assumption is that value itself does not need JSON Array or Object start/end markers), and then write type suffix. This should work for most cases; some sub-classes may want to change this behavior.
|
108
|
+
*
|
109
|
+
* @param value
|
110
|
+
* @param jgen
|
111
|
+
* @param provider
|
112
|
+
* @param typeSer
|
113
|
+
* @throws java.io.IOException
|
114
|
+
* @throws com.fasterxml.jackson.core.JsonGenerationException
|
115
|
+
*/
|
116
|
+
@Override
|
117
|
+
public void serializeWithType(RubyObject value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer)
|
118
|
+
throws IOException, JsonGenerationException {
|
119
|
+
typeSer.writeTypePrefixForScalar(value, jgen);
|
120
|
+
serialize(value, jgen, provider);
|
121
|
+
typeSer.writeTypeSuffixForScalar(value, jgen);
|
98
122
|
}
|
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
123
|
}
|
@@ -1,6 +1,5 @@
|
|
1
1
|
package com.jrjackson;
|
2
2
|
|
3
|
-
import java.util.*;
|
4
3
|
import java.text.SimpleDateFormat;
|
5
4
|
|
6
5
|
import org.jruby.*;
|
@@ -9,73 +8,64 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|
9
8
|
import com.fasterxml.jackson.databind.module.SimpleModule;
|
10
9
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
11
10
|
import com.fasterxml.jackson.core.util.VersionUtil;
|
12
|
-
import com.fasterxml.jackson.databind.ser.std.DateSerializer;
|
13
|
-
import com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer;
|
14
11
|
import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
|
15
12
|
|
16
|
-
public class RubyJacksonModule extends SimpleModule
|
17
|
-
{
|
13
|
+
public class RubyJacksonModule extends SimpleModule {
|
18
14
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
static {
|
24
|
-
static_mapper.registerModule(new AfterburnerModule());
|
25
|
-
static_mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
26
|
-
static_mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"));
|
27
|
-
}
|
15
|
+
private static final ObjectMapper static_mapper = new ObjectMapper().registerModule(
|
16
|
+
new RubyJacksonModule().addSerializer(RubyObject.class, RubyAnySerializer.instance)
|
17
|
+
);
|
28
18
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
19
|
+
static {
|
20
|
+
static_mapper.registerModule(new AfterburnerModule());
|
21
|
+
static_mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
22
|
+
static_mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"));
|
23
|
+
}
|
33
24
|
|
34
|
-
|
35
|
-
|
36
|
-
if (key == "raw") {
|
37
|
-
return static_mapper;
|
25
|
+
private RubyJacksonModule() {
|
26
|
+
super("JrJacksonStrModule", VersionUtil.versionFor(RubyJacksonModule.class));
|
38
27
|
}
|
39
28
|
|
40
|
-
ObjectMapper
|
41
|
-
|
42
|
-
|
29
|
+
public static ObjectMapper mappedAs(String key, Ruby ruby) {
|
30
|
+
if ("raw".equals(key)) {
|
31
|
+
return static_mapper;
|
32
|
+
}
|
43
33
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
);
|
48
|
-
}
|
49
|
-
else {
|
50
|
-
mapper.registerModule(
|
51
|
-
asStr(ruby)
|
52
|
-
);
|
53
|
-
}
|
54
|
-
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
55
|
-
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"));
|
56
|
-
return mapper;
|
57
|
-
}
|
34
|
+
ObjectMapper mapper = new ObjectMapper().registerModule(
|
35
|
+
new AfterburnerModule()
|
36
|
+
);
|
58
37
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
38
|
+
if ("sym".equals(key)) {
|
39
|
+
mapper.registerModule(
|
40
|
+
asSym(ruby)
|
41
|
+
);
|
42
|
+
} else {
|
43
|
+
mapper.registerModule(
|
44
|
+
asStr(ruby)
|
45
|
+
);
|
46
|
+
}
|
47
|
+
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
48
|
+
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"));
|
49
|
+
return mapper;
|
50
|
+
}
|
63
51
|
|
64
|
-
|
65
|
-
|
66
|
-
return
|
67
|
-
|
68
|
-
)
|
69
|
-
|
70
|
-
|
71
|
-
|
52
|
+
// public static SimpleModule asRaw()
|
53
|
+
// {
|
54
|
+
// return static_mapper;
|
55
|
+
// }
|
56
|
+
public static SimpleModule asSym(Ruby ruby) {
|
57
|
+
return new RubyJacksonModule().addSerializer(
|
58
|
+
RubyObject.class, RubyAnySerializer.instance
|
59
|
+
).addDeserializer(
|
60
|
+
Object.class, new RubyObjectDeserializer().withRuby(ruby).setSymbolStrategy()
|
61
|
+
);
|
62
|
+
}
|
72
63
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
}
|
64
|
+
public static SimpleModule asStr(Ruby ruby) {
|
65
|
+
return new RubyJacksonModule().addSerializer(
|
66
|
+
RubyObject.class, RubyAnySerializer.instance
|
67
|
+
).addDeserializer(
|
68
|
+
Object.class, new RubyObjectDeserializer().withRuby(ruby).setStringStrategy()
|
69
|
+
);
|
70
|
+
}
|
81
71
|
}
|
@@ -6,7 +6,7 @@ import java.io.IOException;
|
|
6
6
|
import org.jruby.Ruby;
|
7
7
|
import org.jruby.RubyObject;
|
8
8
|
|
9
|
-
public interface RubyKeyConverter
|
10
|
-
|
11
|
-
|
9
|
+
public interface RubyKeyConverter {
|
10
|
+
|
11
|
+
public RubyObject convert(Ruby ruby, JsonParser jp) throws IOException;
|
12
12
|
}
|
@@ -16,173 +16,176 @@ import org.jruby.RubyArray;
|
|
16
16
|
import org.jruby.RubyHash;
|
17
17
|
import org.jruby.javasupport.util.RuntimeHelpers;
|
18
18
|
|
19
|
-
|
20
19
|
public class RubyObjectDeserializer
|
21
|
-
|
22
|
-
{
|
23
|
-
private static final long serialVersionUID = 1L;
|
24
|
-
|
25
|
-
// private final static RubyObject[] NO_OBJECTS = new RubyObject[0];
|
26
|
-
|
27
|
-
private Ruby _ruby;
|
28
|
-
|
29
|
-
private RubyKeyConverter converter;
|
30
|
-
|
31
|
-
public RubyObjectDeserializer() {
|
32
|
-
super(RubyObject.class);
|
33
|
-
}
|
34
|
-
|
35
|
-
public RubyObjectDeserializer withRuby(Ruby ruby)
|
36
|
-
{
|
37
|
-
_ruby = ruby;
|
38
|
-
return this;
|
39
|
-
}
|
40
|
-
|
41
|
-
public RubyObjectDeserializer setStringStrategy()
|
42
|
-
{
|
43
|
-
converter = new RubyStringConverter();
|
44
|
-
return this;
|
45
|
-
}
|
46
|
-
|
47
|
-
public RubyObjectDeserializer setSymbolStrategy()
|
48
|
-
{
|
49
|
-
converter = new RubySymbolConverter();
|
50
|
-
return this;
|
51
|
-
}
|
52
|
-
|
53
|
-
/**
|
54
|
-
/**********************************************************
|
55
|
-
/* Deserializer API
|
56
|
-
/**********************************************************
|
57
|
-
*/
|
58
|
-
|
59
|
-
@Override
|
60
|
-
public RubyObject deserialize(JsonParser jp, DeserializationContext ctxt)
|
61
|
-
throws IOException, JsonProcessingException
|
62
|
-
{
|
63
|
-
switch (jp.getCurrentToken()) {
|
64
|
-
case START_OBJECT:
|
65
|
-
return mapObject(jp, ctxt);
|
66
|
-
|
67
|
-
case START_ARRAY:
|
68
|
-
return mapArray(jp, ctxt);
|
69
|
-
|
70
|
-
case FIELD_NAME:
|
71
|
-
return converter.convert(_ruby, jp);
|
72
|
-
|
73
|
-
case VALUE_EMBEDDED_OBJECT:
|
74
|
-
return RubyUtils.rubyObject(_ruby, jp.getEmbeddedObject());
|
75
|
-
|
76
|
-
case VALUE_STRING:
|
77
|
-
// return RubyUtils.rubyString(_ruby, jp.getText().getBytes("UTF-8"));
|
78
|
-
return RubyUtils.rubyString(_ruby, jp.getText());
|
79
|
-
|
80
|
-
case VALUE_NUMBER_INT:
|
81
|
-
/* [JACKSON-100]: caller may want to get all integral values
|
82
|
-
* returned as BigInteger, for consistency
|
83
|
-
*/
|
84
|
-
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS)) {
|
85
|
-
return RubyUtils.rubyBignum(_ruby, jp.getBigIntegerValue());
|
86
|
-
}
|
87
|
-
return RubyUtils.rubyFixnum(_ruby, jp.getLongValue());
|
88
|
-
|
89
|
-
case VALUE_NUMBER_FLOAT:
|
90
|
-
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
|
91
|
-
return RubyUtils.rubyBigDecimal(_ruby, jp.getDecimalValue());
|
92
|
-
}
|
93
|
-
return RubyUtils.rubyFloat(_ruby, jp.getDoubleValue());
|
20
|
+
extends StdDeserializer<RubyObject> {
|
94
21
|
|
95
|
-
|
96
|
-
return _ruby.newBoolean(Boolean.TRUE);
|
22
|
+
private static final long serialVersionUID = 1L;
|
97
23
|
|
98
|
-
|
99
|
-
return _ruby.newBoolean(Boolean.FALSE);
|
24
|
+
private Ruby _ruby;
|
100
25
|
|
101
|
-
|
102
|
-
return (RubyObject)_ruby.getNil();
|
26
|
+
private RubyKeyConverter converter;
|
103
27
|
|
104
|
-
|
105
|
-
|
106
|
-
default:
|
107
|
-
throw ctxt.mappingException(Object.class);
|
28
|
+
public RubyObjectDeserializer() {
|
29
|
+
super(RubyObject.class);
|
108
30
|
}
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
/* Internal methods
|
114
|
-
/**********************************************************
|
115
|
-
*/
|
116
|
-
|
117
|
-
/**
|
118
|
-
* Method called to map a JSON Array into a Java value.
|
119
|
-
*/
|
120
|
-
protected RubyObject mapArray(JsonParser jp, DeserializationContext ctxt)
|
121
|
-
throws IOException, JsonProcessingException
|
122
|
-
{
|
123
|
-
// if (ctxt.isEnabled(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY)) {
|
124
|
-
// return mapArrayToArray(jp, ctxt);
|
125
|
-
// }
|
126
|
-
// Minor optimization to handle small lists (default size for ArrayList is 10)
|
127
|
-
if (jp.nextToken() == JsonToken.END_ARRAY) {
|
128
|
-
return RubyArray.newArray(_ruby);
|
31
|
+
|
32
|
+
public RubyObjectDeserializer withRuby(Ruby ruby) {
|
33
|
+
_ruby = ruby;
|
34
|
+
return this;
|
129
35
|
}
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
do {
|
135
|
-
Object value = deserialize(jp, ctxt);
|
136
|
-
++totalSize;
|
137
|
-
if (ptr >= values.length) {
|
138
|
-
values = buffer.appendCompletedChunk(values);
|
139
|
-
ptr = 0;
|
140
|
-
}
|
141
|
-
values[ptr++] = value;
|
142
|
-
} while (jp.nextToken() != JsonToken.END_ARRAY);
|
143
|
-
// let's create almost full array, with 1/8 slack
|
144
|
-
RubyArray result = RubyArray.newArray(_ruby, (totalSize + (totalSize >> 3) + 1));
|
145
|
-
buffer.completeAndClearBuffer(values, ptr, result);
|
146
|
-
return result;
|
147
|
-
}
|
148
|
-
|
149
|
-
/**
|
150
|
-
* Method called to map a JSON Object into a Java value.
|
151
|
-
*/
|
152
|
-
protected RubyObject mapObject(JsonParser jp, DeserializationContext ctxt)
|
153
|
-
throws IOException, JsonProcessingException
|
154
|
-
{
|
155
|
-
JsonToken t = jp.getCurrentToken();
|
156
|
-
if (t == JsonToken.START_OBJECT) {
|
157
|
-
t = jp.nextToken();
|
36
|
+
|
37
|
+
public RubyObjectDeserializer setStringStrategy() {
|
38
|
+
converter = new RubyStringConverter();
|
39
|
+
return this;
|
158
40
|
}
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
41
|
+
|
42
|
+
public RubyObjectDeserializer setSymbolStrategy() {
|
43
|
+
converter = new RubySymbolConverter();
|
44
|
+
return this;
|
163
45
|
}
|
164
46
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
47
|
+
/**
|
48
|
+
* /**********************************************************
|
49
|
+
* /* Deserializer API /**********************************************************
|
50
|
+
* @param jp
|
51
|
+
* @param ctxt
|
52
|
+
* @return
|
53
|
+
* @throws java.io.IOException
|
54
|
+
* @throws com.fasterxml.jackson.core.JsonProcessingException
|
55
|
+
*/
|
56
|
+
|
57
|
+
@Override
|
58
|
+
public RubyObject deserialize(JsonParser jp, DeserializationContext ctxt)
|
59
|
+
throws IOException, JsonProcessingException {
|
60
|
+
switch (jp.getCurrentToken()) {
|
61
|
+
case START_OBJECT:
|
62
|
+
return mapObject(jp, ctxt);
|
63
|
+
|
64
|
+
case START_ARRAY:
|
65
|
+
return mapArray(jp, ctxt);
|
66
|
+
|
67
|
+
case FIELD_NAME:
|
68
|
+
return converter.convert(_ruby, jp);
|
69
|
+
|
70
|
+
case VALUE_EMBEDDED_OBJECT:
|
71
|
+
return RubyUtils.rubyObject(_ruby, jp.getEmbeddedObject());
|
72
|
+
|
73
|
+
case VALUE_STRING:
|
74
|
+
// return RubyUtils.rubyString(_ruby, jp.getText().getBytes("UTF-8"));
|
75
|
+
return RubyUtils.rubyString(_ruby, jp.getText());
|
76
|
+
|
77
|
+
case VALUE_NUMBER_INT:
|
78
|
+
/* [JACKSON-100]: caller may want to get all integral values
|
79
|
+
* returned as BigInteger, for consistency
|
80
|
+
*/
|
81
|
+
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS)) {
|
82
|
+
return RubyUtils.rubyBignum(_ruby, jp.getBigIntegerValue());
|
83
|
+
}
|
84
|
+
return RubyUtils.rubyFixnum(_ruby, jp.getLongValue());
|
85
|
+
|
86
|
+
case VALUE_NUMBER_FLOAT:
|
87
|
+
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
|
88
|
+
return RubyUtils.rubyBigDecimal(_ruby, jp.getDecimalValue());
|
89
|
+
}
|
90
|
+
return RubyUtils.rubyFloat(_ruby, jp.getDoubleValue());
|
91
|
+
|
92
|
+
case VALUE_TRUE:
|
93
|
+
return _ruby.newBoolean(Boolean.TRUE);
|
94
|
+
|
95
|
+
case VALUE_FALSE:
|
96
|
+
return _ruby.newBoolean(Boolean.FALSE);
|
97
|
+
|
98
|
+
case VALUE_NULL: // should not get this but...
|
99
|
+
return (RubyObject) _ruby.getNil();
|
100
|
+
|
101
|
+
case END_ARRAY: // invalid
|
102
|
+
case END_OBJECT: // invalid
|
103
|
+
default:
|
104
|
+
throw ctxt.mappingException(Object.class);
|
105
|
+
}
|
170
106
|
}
|
171
107
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
108
|
+
/**
|
109
|
+
* /**********************************************************
|
110
|
+
* /* Internal methods /**********************************************************
|
111
|
+
*/
|
112
|
+
/**
|
113
|
+
* Method called to map a JSON Array into a Java value.
|
114
|
+
* @param jp
|
115
|
+
* @param ctxt
|
116
|
+
* @return RubyObject
|
117
|
+
* @throws java.io.IOException
|
118
|
+
* @throws com.fasterxml.jackson.core.JsonProcessingException
|
119
|
+
*/
|
120
|
+
protected RubyObject mapArray(JsonParser jp, DeserializationContext ctxt)
|
121
|
+
throws IOException, JsonProcessingException {
|
122
|
+
// if (ctxt.isEnabled(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY)) {
|
123
|
+
// return mapArrayToArray(jp, ctxt);
|
124
|
+
// }
|
125
|
+
// Minor optimization to handle small lists (default size for ArrayList is 10)
|
126
|
+
if (jp.nextToken() == JsonToken.END_ARRAY) {
|
127
|
+
return RubyArray.newArray(_ruby);
|
128
|
+
}
|
129
|
+
ObjectBuffer buffer = ctxt.leaseObjectBuffer();
|
130
|
+
Object[] values = buffer.resetAndStart();
|
131
|
+
int ptr = 0;
|
132
|
+
long totalSize = 0;
|
133
|
+
do {
|
134
|
+
Object value = deserialize(jp, ctxt);
|
135
|
+
++totalSize;
|
136
|
+
if (ptr >= values.length) {
|
137
|
+
values = buffer.appendCompletedChunk(values);
|
138
|
+
ptr = 0;
|
139
|
+
}
|
140
|
+
values[ptr++] = value;
|
141
|
+
} while (jp.nextToken() != JsonToken.END_ARRAY);
|
142
|
+
// let's create almost full array, with 1/8 slack
|
143
|
+
RubyArray result = RubyArray.newArray(_ruby, (totalSize + (totalSize >> 3) + 1));
|
144
|
+
buffer.completeAndClearBuffer(values, ptr, result);
|
145
|
+
return result;
|
177
146
|
}
|
178
147
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
148
|
+
/**
|
149
|
+
* Method called to map a JSON Object into a Java value.
|
150
|
+
* @param jp
|
151
|
+
* @param ctxt
|
152
|
+
* @return RubyObject
|
153
|
+
* @throws java.io.IOException
|
154
|
+
* @throws com.fasterxml.jackson.core.JsonProcessingException
|
155
|
+
*/
|
156
|
+
protected RubyObject mapObject(JsonParser jp, DeserializationContext ctxt)
|
157
|
+
throws IOException, JsonProcessingException {
|
158
|
+
JsonToken t = jp.getCurrentToken();
|
159
|
+
if (t == JsonToken.START_OBJECT) {
|
160
|
+
t = jp.nextToken();
|
161
|
+
}
|
162
|
+
// 1.6: minor optimization; let's handle 1 and 2 entry cases separately
|
163
|
+
if (t != JsonToken.FIELD_NAME) { // and empty one too
|
164
|
+
// empty map might work; but caller may want to modify... so better just give small modifiable
|
165
|
+
return RubyHash.newHash(_ruby);
|
166
|
+
}
|
167
|
+
|
168
|
+
RubyObject field1 = converter.convert(_ruby, jp);
|
169
|
+
jp.nextToken();
|
170
|
+
RubyObject value1 = deserialize(jp, ctxt);
|
171
|
+
if (jp.nextToken() != JsonToken.FIELD_NAME) { // single entry; but we want modifiable
|
172
|
+
return RuntimeHelpers.constructHash(_ruby, field1, value1);
|
173
|
+
}
|
174
|
+
|
175
|
+
RubyObject field2 = converter.convert(_ruby, jp);
|
176
|
+
jp.nextToken();
|
177
|
+
RubyObject value2 = deserialize(jp, ctxt);
|
178
|
+
if (jp.nextToken() != JsonToken.FIELD_NAME) {
|
179
|
+
return RuntimeHelpers.constructHash(_ruby, field1, value1, field2, value2);
|
180
|
+
}
|
181
|
+
|
182
|
+
// And then the general case; default map size is 16
|
183
|
+
RubyHash result = RuntimeHelpers.constructHash(_ruby, field1, value1, field2, value2);
|
184
|
+
do {
|
185
|
+
RubyObject fieldName = converter.convert(_ruby, jp);
|
186
|
+
jp.nextToken();
|
187
|
+
result.fastASetCheckString(_ruby, fieldName, deserialize(jp, ctxt));
|
188
|
+
} while (jp.nextToken() != JsonToken.END_OBJECT);
|
189
|
+
return result;
|
190
|
+
}
|
188
191
|
}
|
@@ -6,9 +6,10 @@ import java.io.IOException;
|
|
6
6
|
import org.jruby.Ruby;
|
7
7
|
import org.jruby.RubyObject;
|
8
8
|
|
9
|
-
public class RubyStringConverter implements RubyKeyConverter
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
public class RubyStringConverter implements RubyKeyConverter {
|
10
|
+
|
11
|
+
@Override
|
12
|
+
public RubyObject convert(Ruby ruby, JsonParser jp) throws IOException {
|
13
|
+
return RubyUtils.rubyString(ruby, jp.getText().getBytes());
|
14
|
+
}
|
14
15
|
}
|
@@ -6,9 +6,9 @@ import java.io.IOException;
|
|
6
6
|
import org.jruby.Ruby;
|
7
7
|
import org.jruby.RubyObject;
|
8
8
|
|
9
|
-
public class RubySymbolConverter implements RubyKeyConverter
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
public class RubySymbolConverter implements RubyKeyConverter {
|
10
|
+
|
11
|
+
public RubyObject convert(Ruby ruby, JsonParser jp) throws IOException {
|
12
|
+
return RubyUtils.rubySymbol(ruby, jp.getText());
|
13
|
+
}
|
14
14
|
}
|
@@ -1,6 +1,5 @@
|
|
1
1
|
package com.jrjackson;
|
2
2
|
|
3
|
-
import java.io.IOException;
|
4
3
|
import java.util.*;
|
5
4
|
|
6
5
|
import java.math.BigDecimal;
|
@@ -8,82 +7,65 @@ import java.math.BigInteger;
|
|
8
7
|
|
9
8
|
import org.jruby.*;
|
10
9
|
import org.jruby.javasupport.JavaUtil;
|
11
|
-
import org.jruby.runtime.builtin.IRubyObject;
|
12
10
|
import org.jruby.ext.bigdecimal.RubyBigDecimal;
|
13
|
-
import org.jruby.runtime.Block;
|
14
11
|
import org.jruby.util.SafeDoubleParser;
|
15
12
|
|
16
|
-
public class RubyUtils
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
public static RubyFloat rubyFloat(Ruby ruby, String arg)
|
75
|
-
{
|
76
|
-
double d = SafeDoubleParser.parseDouble(arg);
|
77
|
-
return ruby.newFloat(d);
|
78
|
-
}
|
79
|
-
|
80
|
-
public static RubyBigDecimal rubyBigDecimal(Ruby ruby, BigDecimal arg)
|
81
|
-
{
|
82
|
-
return new RubyBigDecimal(ruby, arg);
|
83
|
-
}
|
84
|
-
|
85
|
-
public static RubyBoolean rubyBoolean(Ruby ruby, Boolean arg)
|
86
|
-
{
|
87
|
-
return ruby.newBoolean(arg);
|
88
|
-
}
|
13
|
+
public class RubyUtils {
|
14
|
+
|
15
|
+
public static RubyObject rubyObject(Ruby ruby, Object node) {
|
16
|
+
return (RubyObject) JavaUtil.convertJavaToRuby(ruby, node);
|
17
|
+
}
|
18
|
+
|
19
|
+
public static RubyString rubyString(Ruby ruby, String node) {
|
20
|
+
return RubyString.newUnicodeString(ruby, node);
|
21
|
+
}
|
22
|
+
|
23
|
+
public static RubyString rubyString(Ruby ruby, byte[] node) {
|
24
|
+
return RubyString.newString(ruby, node);
|
25
|
+
}
|
26
|
+
|
27
|
+
public static RubySymbol rubySymbol(Ruby ruby, String node) {
|
28
|
+
return RubySymbol.newSymbol(ruby, node);
|
29
|
+
}
|
30
|
+
|
31
|
+
public static RubyArray rubyArray(Ruby ruby, Object[] arg) {
|
32
|
+
return (RubyArray) JavaUtil.convertJavaToRuby(ruby, arg);
|
33
|
+
}
|
34
|
+
|
35
|
+
public static RubyArray rubyArray(Ruby ruby, List arg) {
|
36
|
+
return (RubyArray) JavaUtil.convertJavaToRuby(ruby, arg);
|
37
|
+
}
|
38
|
+
|
39
|
+
public static RubyHash rubyHash(Ruby ruby, Map arg) {
|
40
|
+
return (RubyHash) JavaUtil.convertJavaToRuby(ruby, arg);
|
41
|
+
}
|
42
|
+
|
43
|
+
public static RubyFixnum rubyFixnum(Ruby ruby, int arg) {
|
44
|
+
return ruby.newFixnum(arg);
|
45
|
+
}
|
46
|
+
|
47
|
+
public static RubyFixnum rubyFixnum(Ruby ruby, long arg) {
|
48
|
+
return ruby.newFixnum(arg);
|
49
|
+
}
|
50
|
+
|
51
|
+
public static RubyBignum rubyBignum(Ruby ruby, BigInteger arg) {
|
52
|
+
return RubyBignum.newBignum(ruby, arg);
|
53
|
+
}
|
54
|
+
|
55
|
+
public static RubyFloat rubyFloat(Ruby ruby, double arg) {
|
56
|
+
return ruby.newFloat(arg);
|
57
|
+
}
|
58
|
+
|
59
|
+
public static RubyFloat rubyFloat(Ruby ruby, String arg) {
|
60
|
+
double d = SafeDoubleParser.parseDouble(arg);
|
61
|
+
return ruby.newFloat(d);
|
62
|
+
}
|
63
|
+
|
64
|
+
public static RubyBigDecimal rubyBigDecimal(Ruby ruby, BigDecimal arg) {
|
65
|
+
return new RubyBigDecimal(ruby, arg);
|
66
|
+
}
|
67
|
+
|
68
|
+
public static RubyBoolean rubyBoolean(Ruby ruby, Boolean arg) {
|
69
|
+
return ruby.newBoolean(arg);
|
70
|
+
}
|
89
71
|
}
|
data/test/jrjackson_test.rb
CHANGED
@@ -42,6 +42,15 @@ class JrJacksonTest < Test::Unit::TestCase
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
class CustomToTime
|
46
|
+
def initialize(tm = Time.now)
|
47
|
+
@now = tm
|
48
|
+
end
|
49
|
+
def to_time
|
50
|
+
@now
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
45
54
|
CustomStruct = Struct.new(:one, :two, :six)
|
46
55
|
|
47
56
|
def test_threading
|
@@ -78,7 +87,8 @@ class JrJacksonTest < Test::Unit::TestCase
|
|
78
87
|
co2 = CustomToHash.new("uno", :two, 6.0)
|
79
88
|
co3 = CustomToJson.new(1.0, 2, 6.0)
|
80
89
|
co4 = CustomStruct.new(1, 2, 6)
|
81
|
-
|
90
|
+
co5 = CustomToTime.new(dt)
|
91
|
+
source = {'sym' => :a_symbol, 'dt' => dt, 'co1' => co1, 'co2' => co2, 'co3' => co3, 'co4' => co4, 'co5' => co5}
|
82
92
|
json_string = JrJackson::Json.dump(source)
|
83
93
|
expected = {
|
84
94
|
:sym => "a_symbol",
|
@@ -87,6 +97,7 @@ class JrJacksonTest < Test::Unit::TestCase
|
|
87
97
|
:co2 => {:one => "uno", :two => "two", :six => 6.0 },
|
88
98
|
:co3 => {:one => 1.0, :two => 2.0, :six => 6.0 },
|
89
99
|
:co4 => [1, 2, 6],
|
100
|
+
:co5 => dt.strftime("%F %T %Z")
|
90
101
|
}
|
91
102
|
actual = JrJackson::Json.load(json_string, :symbolize_keys => true)
|
92
103
|
assert_equal expected, actual
|
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.
|
4
|
+
version: 0.2.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Guy Boertje
|
@@ -41,7 +41,7 @@ files:
|
|
41
41
|
- jrjackson.gemspec
|
42
42
|
- lib/jrjackson.rb
|
43
43
|
- lib/jrjackson/build_info.rb
|
44
|
-
- lib/jrjackson/jars/jrjackson-1.2.
|
44
|
+
- lib/jrjackson/jars/jrjackson-1.2.9.jar
|
45
45
|
- lib/jrjackson/jrjackson.rb
|
46
46
|
- lib/require_relative_patch.rb
|
47
47
|
- pom.xml
|