jrjackson 0.2.9 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/{.jrubyrc → .__jrubyrc} +2 -2
  3. data/.gitignore +5 -0
  4. data/Gemfile +1 -0
  5. data/alt_bench.rb +46 -0
  6. data/dependency-reduced-pom.xml +6 -5
  7. data/lib/jrjackson/build_info.rb +2 -2
  8. data/lib/jrjackson/jars/jrjackson-1.2.16.jar +0 -0
  9. data/lib/jrjackson/jrjackson.rb +38 -13
  10. data/pom.xml +11 -10
  11. data/run_all_individual_bench.sh +17 -15
  12. data/run_jruby_individual_bench.sh +20 -0
  13. data/run_mri_individual_bench.sh +7 -0
  14. data/src/main/java/com/jrjackson/IParseHandler.java +53 -0
  15. data/src/main/java/com/jrjackson/JavaBigDecimalValueConverter.java +17 -0
  16. data/src/main/java/com/jrjackson/JavaBigIntValueConverter.java +17 -0
  17. data/src/main/java/com/jrjackson/JavaConverter.java +10 -0
  18. data/src/main/java/com/jrjackson/JavaFloatValueConverter.java +16 -0
  19. data/src/main/java/com/jrjackson/JavaHandler.java +118 -0
  20. data/src/main/java/com/jrjackson/JavaLongValueConverter.java +16 -0
  21. data/src/main/java/com/jrjackson/JjParse.java +147 -0
  22. data/src/main/java/com/jrjackson/JrJacksonBase.java +159 -0
  23. data/src/main/java/com/jrjackson/JrJacksonJava.java +81 -0
  24. data/src/main/java/com/jrjackson/JrJacksonRaw.java +59 -102
  25. data/src/main/java/com/jrjackson/JrJacksonRuby.java +117 -0
  26. data/src/main/java/com/jrjackson/JrJacksonSaj.java +26 -0
  27. data/src/main/java/com/jrjackson/JrJacksonSch.java +25 -0
  28. data/src/main/java/com/jrjackson/JrJacksonService.java +15 -0
  29. data/src/main/java/com/jrjackson/JrParse.java +149 -0
  30. data/src/main/java/com/jrjackson/RubyAnySerializer.java +112 -55
  31. data/src/main/java/com/jrjackson/RubyBigDecimalValueConverter.java +18 -0
  32. data/src/main/java/com/jrjackson/RubyBigIntValueConverter.java +21 -0
  33. data/src/main/java/com/jrjackson/RubyConverter.java +12 -0
  34. data/src/main/java/com/jrjackson/RubyDateFormat.java +36 -0
  35. data/src/main/java/com/jrjackson/RubyFloatValueConverter.java +18 -0
  36. data/src/main/java/com/jrjackson/RubyHandler.java +119 -0
  37. data/src/main/java/com/jrjackson/RubyIntValueConverter.java +18 -0
  38. data/src/main/java/com/jrjackson/RubyJacksonModule.java +40 -38
  39. data/src/main/java/com/jrjackson/RubyNameConverter.java +9 -0
  40. data/src/main/java/com/jrjackson/RubyObjectDeserializer.java +24 -33
  41. data/src/main/java/com/jrjackson/RubyStringConverter.java +1 -2
  42. data/src/main/java/com/jrjackson/{RubySymbolConverter.java → RubyStringKeyConverter.java} +3 -2
  43. data/src/main/java/com/jrjackson/RubyStringNameConverter.java +12 -0
  44. data/src/main/java/com/jrjackson/RubySymbolKeyConverter.java +15 -0
  45. data/src/main/java/com/jrjackson/RubySymbolNameConverter.java +12 -0
  46. data/src/main/java/com/jrjackson/RubyUtils.java +40 -1
  47. data/src/main/java/com/jrjackson/SajParse.java +169 -0
  48. data/src/main/java/com/jrjackson/SchParse.java +209 -0
  49. data/src/main/java/com/jrjackson/StreamParse.java +66 -0
  50. data/test/jrjackson_test.rb +271 -6
  51. metadata +49 -17
  52. data/src/test/java/com/jrjackson/jruby/AppTest.java +0 -38
@@ -0,0 +1,169 @@
1
+ package com.jrjackson;
2
+
3
+ import com.fasterxml.jackson.core.JsonParser;
4
+ import com.fasterxml.jackson.core.JsonProcessingException;
5
+ import com.fasterxml.jackson.core.JsonStreamContext;
6
+ import com.fasterxml.jackson.core.JsonLocation;
7
+
8
+ import java.io.IOException;
9
+
10
+ import org.jruby.internal.runtime.methods.DynamicMethod;
11
+ import org.jruby.runtime.ThreadContext;
12
+ import org.jruby.runtime.builtin.IRubyObject;
13
+ import org.jruby.exceptions.RaiseException;
14
+
15
+ /**
16
+ *
17
+ * @author Guy Boertje
18
+ */
19
+ public class SajParse extends StreamParse {
20
+
21
+ protected DynamicMethod _error;
22
+ protected boolean _no_error;
23
+
24
+ public SajParse(ThreadContext ctx, IRubyObject handler)
25
+ throws RaiseException {
26
+ super(ctx, handler);
27
+
28
+ if (_no_add_value) {
29
+ throw ParseError.newParseError(_ruby, "Handler does not implement public API");
30
+ }
31
+ _error = _meta.searchMethod("error");
32
+ _no_error = _error.isUndefined();
33
+
34
+ }
35
+
36
+ @Override
37
+ public IRubyObject deserialize(JsonParser jp) {
38
+
39
+ try {
40
+ while(jp.nextValue() != null) {
41
+ handleCurrentToken(jp);
42
+ }
43
+ }
44
+ catch (JsonProcessingException e) {
45
+ if(!_no_error) {
46
+ JsonLocation location = e.getLocation();
47
+ IRubyObject message = RubyUtils.rubyString(_ruby, e.getMessage());
48
+ IRubyObject line = RubyUtils.rubyFixnum(_ruby, location.getLineNr());
49
+ IRubyObject column = RubyUtils.rubyFixnum(_ruby, location.getColumnNr());
50
+
51
+ _error.call(_ctx, _handler, _meta, "error", message, line, column);
52
+ }
53
+ }
54
+ catch (IOException e) {
55
+ if(!_no_error) {
56
+ IRubyObject message = RubyUtils.rubyString(_ruby, e.getMessage());
57
+ IRubyObject line = RubyUtils.rubyFixnum(_ruby, 1);
58
+ IRubyObject column = RubyUtils.rubyFixnum(_ruby, 1);
59
+
60
+ _error.call(_ctx, _handler, _meta, "error", message, line, column);
61
+ }
62
+ }
63
+
64
+ return _ctx.nil;
65
+ }
66
+
67
+ private void callAddValue(IRubyObject val, IRubyObject key) {
68
+ _add_value.call(_ctx, _handler, _meta, "add_value", val, key);
69
+ }
70
+
71
+ private IRubyObject getParentName(JsonStreamContext x) {
72
+ String parentName = x.getCurrentName();
73
+ IRubyObject parent = _ctx.nil;
74
+
75
+ if (!x.inRoot()) {
76
+ parentName = x.getParent().getCurrentName();
77
+ }
78
+ if (parentName != null) {
79
+ parent = RubyUtils.rubyString(_ruby, parentName);
80
+ }
81
+ return parent;
82
+ }
83
+
84
+ private IRubyObject getFieldName(JsonStreamContext x) {
85
+ String currentName = x.getCurrentName();
86
+ IRubyObject name = _ctx.nil;
87
+
88
+ if (currentName != null) {
89
+ name = RubyUtils.rubyString(_ruby, currentName);
90
+ }
91
+ return name;
92
+ }
93
+
94
+ private void handleCurrentToken(JsonParser jp)
95
+ throws IOException, JsonProcessingException {
96
+
97
+ JsonStreamContext cx = jp.getParsingContext();
98
+
99
+ IRubyObject value;
100
+
101
+ switch (jp.getCurrentToken()) {
102
+ case START_OBJECT:
103
+ if (!_no_hash_start) {
104
+ _hash_start.call(_ctx, _handler, _meta, "hash_start", getParentName(cx));
105
+ }
106
+ break;
107
+
108
+ case START_ARRAY:
109
+ if (!_no_array_start) {
110
+ _array_start.call(_ctx, _handler, _meta, "array_start", getParentName(cx));
111
+ }
112
+ break;
113
+
114
+ case FIELD_NAME:
115
+ break;
116
+
117
+ case VALUE_EMBEDDED_OBJECT:
118
+ value = RubyUtils.rubyObject(_ruby, jp.getEmbeddedObject());
119
+ callAddValue(value, getFieldName(cx));
120
+ break;
121
+
122
+ case VALUE_STRING:
123
+ value = keyConverter.convert(_ruby, jp);
124
+ callAddValue(value, getFieldName(cx));
125
+ break;
126
+
127
+ case VALUE_NUMBER_INT:
128
+ /* [JACKSON-100]: caller may want to get all integral values
129
+ * returned as BigInteger, for consistency
130
+ */
131
+ JsonParser.NumberType numberType = jp.getNumberType();
132
+ value = RubyUtils.rubyBignum(_ruby, jp.getBigIntegerValue());
133
+ callAddValue(value, getFieldName(cx));
134
+ break;
135
+
136
+ case VALUE_NUMBER_FLOAT:
137
+ value = RubyUtils.rubyBigDecimal(_ruby, jp.getDecimalValue());
138
+ callAddValue(value, getFieldName(cx));
139
+ break;
140
+
141
+ case VALUE_TRUE:
142
+ value = _ruby.newBoolean(Boolean.TRUE);
143
+ callAddValue(value, getFieldName(cx));
144
+ break;
145
+
146
+ case VALUE_FALSE:
147
+ value = _ruby.newBoolean(Boolean.FALSE);
148
+ callAddValue(value, getFieldName(cx));
149
+ break;
150
+
151
+ case VALUE_NULL: // should not get this but...
152
+ value = _ctx.nil;
153
+ callAddValue(value, getFieldName(cx));
154
+ break;
155
+
156
+ case END_ARRAY:
157
+ if (!_no_array_end) {
158
+ _array_end.call(_ctx, _handler, _meta, "array_end", getFieldName(cx));
159
+ }
160
+ break;
161
+
162
+ case END_OBJECT:
163
+ if (!_no_hash_end) {
164
+ _hash_end.call(_ctx, _handler, _meta, "hash_end", getFieldName(cx));
165
+ }
166
+ break;
167
+ }
168
+ }
169
+ }
@@ -0,0 +1,209 @@
1
+ package com.jrjackson;
2
+
3
+ import com.fasterxml.jackson.core.JsonParser;
4
+ import com.fasterxml.jackson.core.JsonProcessingException;
5
+ import com.fasterxml.jackson.core.JsonStreamContext;
6
+ import java.io.IOException;
7
+ import java.util.HashMap;
8
+
9
+ import org.jruby.internal.runtime.methods.DynamicMethod;
10
+ import org.jruby.runtime.ThreadContext;
11
+ import org.jruby.runtime.builtin.IRubyObject;
12
+ import org.jruby.RubyString;
13
+ import org.jruby.exceptions.RaiseException;
14
+
15
+ /**
16
+ *
17
+ * @author Guy Boertje
18
+ */
19
+ public class SchParse extends StreamParse {
20
+
21
+ protected final DynamicMethod _hash_key;
22
+ protected final boolean _no_hash_key;
23
+
24
+ protected final DynamicMethod _hash_set;
25
+ protected final boolean _no_hash_set;
26
+
27
+ protected final DynamicMethod _array_append;
28
+ protected final boolean _no_array_append;
29
+
30
+ protected final HashMap<JsonStreamContext, IRubyObject> _objectMap = new HashMap<JsonStreamContext, IRubyObject>();
31
+ protected JsonStreamContext _deepestContext;
32
+
33
+ public SchParse(ThreadContext ctx, IRubyObject handler)
34
+ throws RaiseException {
35
+ super(ctx, handler);
36
+
37
+ _hash_key = _meta.searchMethod("hash_key");
38
+ _no_hash_key = _hash_key.isUndefined();
39
+
40
+ _hash_set = _meta.searchMethod("hash_set");
41
+ _no_hash_set = _hash_set.isUndefined();
42
+
43
+ _array_append = _meta.searchMethod("array_append");
44
+ _no_array_append = _array_append.isUndefined();
45
+
46
+ //_hash_key is optional
47
+ if (
48
+ _no_hash_start || _no_hash_end ||
49
+ _no_array_start || _no_array_end ||
50
+ _no_add_value || _no_hash_set || _no_array_append
51
+ ) {
52
+ throw ParseError.newParseError(_ruby, "Handler does not implement public API");
53
+ }
54
+ }
55
+
56
+ @Override
57
+ public IRubyObject deserialize(JsonParser jp) throws RaiseException {
58
+ try {
59
+
60
+ while (jp.nextValue() != null) {
61
+ handleCurrentToken(jp);
62
+ }
63
+ return _ctx.nil;
64
+
65
+ } catch (JsonProcessingException e) {
66
+ throw ParseError.newParseError(_ruby, e.getLocalizedMessage());
67
+ } catch (IOException e) {
68
+ throw _ruby.newIOError(e.getLocalizedMessage());
69
+ }
70
+ }
71
+
72
+ private void callAddValue(JsonStreamContext x) {
73
+ JsonStreamContext px = x.getParent();
74
+ IRubyObject target = _objectMap.get(x);
75
+ IRubyObject dtarget = _objectMap.get(_deepestContext);
76
+
77
+ if (px == null) {
78
+ _add_value.call(_ctx, _handler, _meta, "add_value", dtarget);
79
+ return;
80
+ }
81
+
82
+ if (x.inArray()) {
83
+ _array_append.call(_ctx, _handler, _meta, "array_append", target, dtarget);
84
+ } else if (x.inObject()) {
85
+ IRubyObject treatedKey = callHashKey(x);
86
+ _hash_set.call(_ctx, _handler, _meta, "hash_set", target, treatedKey, dtarget);
87
+ } else {
88
+ _add_value.call(_ctx, _handler, _meta, "add_value", target);
89
+ }
90
+ }
91
+
92
+ private void callAddValue(JsonStreamContext x, IRubyObject val) {
93
+ IRubyObject target = _objectMap.get(x);
94
+
95
+ if (x.inArray()) {
96
+ _array_append.call(_ctx, _handler, _meta, "array_append", target, val);
97
+ } else if (x.inObject()) {
98
+ IRubyObject treatedKey = callHashKey(x);
99
+ _hash_set.call(_ctx, _handler, _meta, "hash_set", target, treatedKey, val);
100
+ } else {
101
+ _add_value.call(_ctx, _handler, _meta, "add_value", val);
102
+ }
103
+ }
104
+
105
+ private IRubyObject callHashKey(JsonStreamContext x) {
106
+ String k = x.getCurrentName();
107
+ if (k == null) {
108
+ return _ctx.nil;
109
+ }
110
+ RubyString key = RubyUtils.rubyString(_ruby, k);
111
+ if (_no_hash_key) {
112
+ return key;
113
+ }
114
+ return _hash_key.call(_ctx, _handler, _meta, "hash_key", key);
115
+ }
116
+
117
+ private void handleCurrentToken(JsonParser jp)
118
+ throws IOException, JsonProcessingException {
119
+
120
+ JsonStreamContext cx = jp.getParsingContext();
121
+ IRubyObject value;
122
+ IRubyObject rubyObject;
123
+
124
+ switch (jp.getCurrentToken()) {
125
+ case START_OBJECT:
126
+ _deepestContext = cx;
127
+ rubyObject = _hash_start.call(_ctx, _handler, _meta, "hash_start");
128
+ _objectMap.put(cx, rubyObject);
129
+ break;
130
+
131
+ case START_ARRAY:
132
+ _deepestContext = cx;
133
+ rubyObject = _array_start.call(_ctx, _handler, _meta, "array_start");
134
+ _objectMap.put(cx, rubyObject);
135
+ break;
136
+
137
+ case FIELD_NAME:
138
+ break;
139
+
140
+ case VALUE_EMBEDDED_OBJECT:
141
+ value = RubyUtils.rubyObject(_ruby, jp.getEmbeddedObject());
142
+ callAddValue(cx, value);
143
+ break;
144
+
145
+ case VALUE_STRING:
146
+ value = keyConverter.convert(_ruby, jp);
147
+ callAddValue(cx, value);
148
+ break;
149
+
150
+ case VALUE_NUMBER_INT:
151
+ /* [JACKSON-100]: caller may want to get all integral values
152
+ * returned as BigInteger, for consistency
153
+ */
154
+ JsonParser.NumberType numberType = jp.getNumberType();
155
+ value = RubyUtils.rubyBignum(_ruby, jp.getBigIntegerValue());
156
+ callAddValue(cx, value);
157
+ break;
158
+
159
+ case VALUE_NUMBER_FLOAT:
160
+ value = RubyUtils.rubyBigDecimal(_ruby, jp.getDecimalValue());
161
+ callAddValue(cx, value);
162
+ break;
163
+
164
+ case VALUE_TRUE:
165
+ value = _ruby.newBoolean(Boolean.TRUE);
166
+ callAddValue(cx, value);
167
+ break;
168
+
169
+ case VALUE_FALSE:
170
+ value = _ruby.newBoolean(Boolean.FALSE);
171
+ callAddValue(cx, value);
172
+ break;
173
+
174
+ case VALUE_NULL: // should not get this but...
175
+ value = _ctx.nil;
176
+ callAddValue(cx, value);
177
+ break;
178
+
179
+ case END_ARRAY:
180
+ _array_end.call(_ctx, _handler, _meta, "array_end");
181
+ callAddValue(cx);
182
+ _deepestContext = cx;
183
+ break;
184
+
185
+ case END_OBJECT:
186
+ _hash_end.call(_ctx, _handler, _meta, "hash_end");
187
+ callAddValue(cx);
188
+ _deepestContext = cx;
189
+ break;
190
+ }
191
+
192
+ }
193
+
194
+ }
195
+ // System.out.println("--- callAddValue final ---");
196
+ // if (px != null) {
197
+ // System.out.println("-------- parent --------");
198
+ // System.out.println(px.getTypeDesc());
199
+ // System.out.println(px.getCurrentName());
200
+ // }
201
+ // System.out.println("-------- current --------");
202
+ // System.out.println(x.getTypeDesc());
203
+ // System.out.println(x.getCurrentName());
204
+ // System.out.println(target);
205
+ //
206
+ // System.out.println("-------- deepest --------");
207
+ // System.out.println(_deepestContext.getTypeDesc());
208
+ // System.out.println(_deepestContext.getCurrentName());
209
+ // System.out.println(dtarget);
@@ -0,0 +1,66 @@
1
+ package com.jrjackson;
2
+
3
+ import com.fasterxml.jackson.core.JsonParser;
4
+
5
+ import org.jruby.Ruby;
6
+ import org.jruby.RubyClass;
7
+ import org.jruby.internal.runtime.methods.DynamicMethod;
8
+ import org.jruby.runtime.ThreadContext;
9
+ import org.jruby.runtime.builtin.IRubyObject;
10
+ import org.jruby.exceptions.RaiseException;
11
+
12
+ /**
13
+ *
14
+ * @author Guy Boertje
15
+ */
16
+ public abstract class StreamParse {
17
+
18
+ protected final ThreadContext _ctx;
19
+ protected final Ruby _ruby;
20
+ protected final IRubyObject _handler;
21
+ protected final RubyClass _meta;
22
+ protected final RubyStringConverter keyConverter = new RubyStringConverter();
23
+
24
+ protected final DynamicMethod _hash_start;
25
+ protected final boolean _no_hash_start;
26
+
27
+ protected final DynamicMethod _hash_end;
28
+ protected final boolean _no_hash_end;
29
+
30
+ protected final DynamicMethod _array_start;
31
+ protected final boolean _no_array_start;
32
+
33
+ protected final DynamicMethod _array_end;
34
+ protected final boolean _no_array_end;
35
+
36
+ protected final DynamicMethod _add_value;
37
+ protected final boolean _no_add_value;
38
+
39
+ public StreamParse(ThreadContext ctx, IRubyObject handler)
40
+ throws RaiseException {
41
+
42
+ _ctx = ctx;
43
+ _ruby = ctx.runtime;
44
+ _handler = handler;
45
+ _meta = _handler.getMetaClass();
46
+
47
+ _add_value = _meta.searchMethod("add_value");
48
+ _no_add_value = _add_value.isUndefined();
49
+
50
+ _hash_start = _meta.searchMethod("hash_start");
51
+ _no_hash_start = _hash_start.isUndefined();
52
+
53
+ _hash_end = _meta.searchMethod("hash_end");
54
+ _no_hash_end = _hash_end.isUndefined();
55
+
56
+ _array_start = _meta.searchMethod("array_start");
57
+ _no_array_start = _array_start.isUndefined();
58
+
59
+ _array_end = _meta.searchMethod("array_end");
60
+ _no_array_end = _array_end.isUndefined();
61
+
62
+ }
63
+
64
+ public abstract IRubyObject deserialize(JsonParser jp)
65
+ throws RaiseException;
66
+ }