src/main/java/com/jrjackson/JrJacksonRaw.java in jrjackson-0.1.1 vs src/main/java/com/jrjackson/JrJacksonRaw.java in jrjackson-0.2.0
- old
+ new
@@ -2,70 +2,155 @@
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyObject;
import org.jruby.RubyString;
+import org.jruby.RubySymbol;
+import org.jruby.RubyHash;
import org.jruby.RubyIO;
import org.jruby.anno.JRubyMethod;
import org.jruby.anno.JRubyModule;
import org.jruby.exceptions.RaiseException;
import org.jruby.ext.stringio.RubyStringIO;
import org.jruby.java.addons.IOJavaAddons;
-import org.jruby.javasupport.JavaUtil;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
-import org.jruby.util.RubyDateFormat;
import java.io.InputStream;
import java.io.IOException;
-import java.text.DateFormat;
import java.util.*;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.core.JsonProcessingException;
@JRubyModule(name = "JrJacksonRaw")
public class JrJacksonRaw extends RubyObject {
- protected static final ObjectMapper mapper = new ObjectMapper();
+ private static final HashMap<String, ObjectMapper> mappers = new HashMap<String, ObjectMapper>(3);
+ private static final HashMap<String, RubySymbol> symbols = new HashMap<String, RubySymbol>(3);
+ private static final Ruby _ruby = Ruby.getGlobalRuntime();
+
static {
- mapper.setDateFormat(new RubyDateFormat("yyyy-MM-dd HH:mm:ss z", Locale.US, true));
+ mappers.put("str",
+ RubyJacksonModule.mappedAs("str")
+ );
+ mappers.put("sym",
+ RubyJacksonModule.mappedAs("sym")
+ );
+ mappers.put("raw",
+ RubyJacksonModule.mappedAs("raw")
+ );
+ symbols.put("sym",
+ RubyUtils.rubySymbol(_ruby, "symbolize_keys")
+ );
+ symbols.put("raw",
+ RubyUtils.rubySymbol(_ruby, "raw")
+ );
+ symbols.put("bigdecimal",
+ RubyUtils.rubySymbol(_ruby, "use_bigdecimal")
+ );
}
public JrJacksonRaw(Ruby ruby, RubyClass metaclass) {
super(ruby, metaclass);
}
- @JRubyMethod(module = true, name = {"parse", "load"}, required = 1)
- public static IRubyObject parse(ThreadContext context, IRubyObject self, IRubyObject arg) {
+ private static boolean flagged(RubyHash opts, String key) {
+ Object val = opts.get(symbols.get(key));
+ if (val == null) {
+ return false;
+ }
+ return (Boolean) val;
+ }
+
+ // deserialize
+ @JRubyMethod(module = true, name = {"parse", "load"}, required = 2)
+ public static IRubyObject parse(ThreadContext context, IRubyObject self, IRubyObject arg, IRubyObject opts)
+ throws IOException
+ {
+ RubyHash options = null;
+ String key = "str";
+ ObjectMapper local;
+
+ if (opts != context.nil) {
+ options = opts.convertToHash();
+ if (flagged(options, "sym")) {
+ key = "sym";
+ }
+ if (flagged(options, "raw")) {
+ key = "raw";
+ }
+ local = mappers.get(key).copy();
+ if (flagged(options, "bigdecimal")) {
+ local.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
+ }
+ else {
+ local.disable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
+ }
+ }
+ else {
+ local = mappers.get(key).copy();
+ }
+ return _parse(context, arg, local);
+ }
+
+ @JRubyMethod(module = true, name = {"parse_raw", "load_raw"}, required = 1)
+ public static IRubyObject parse_raw(ThreadContext context, IRubyObject self, IRubyObject arg)
+ throws IOException
+ {
+ return _parse(context, arg, mappers.get("raw"));
+ }
+
+ @JRubyMethod(module = true, name = {"parse_sym", "load_sym"}, required = 1)
+ public static IRubyObject parse_sym(ThreadContext context, IRubyObject self, IRubyObject arg)
+ throws IOException
+ {
+ return _parse(context, arg, mappers.get("sym"));
+ }
+
+ @JRubyMethod(module = true, name = {"parse_str", "load_str"}, required = 1)
+ public static IRubyObject parse_str(ThreadContext context, IRubyObject self, IRubyObject arg)
+ throws IOException
+ {
+ return _parse(context, arg, mappers.get("str"));
+ }
+
+ public static IRubyObject _parse(ThreadContext context, IRubyObject arg, ObjectMapper mapper)
+ throws IOException
+ {
Ruby ruby = context.getRuntime();
+
try {
Object o;
if (arg instanceof RubyString) {
- o = mapper.readValue(arg.toString(), Object.class);
+ o = mapper.readValue(
+ arg.toString(), Object.class
+ );
} else if ((arg instanceof RubyIO) || (arg instanceof RubyStringIO)) {
IRubyObject stream = IOJavaAddons.AnyIO.any_to_inputstream(context, arg);
- o = mapper.readValue((InputStream)stream.toJava(InputStream.class), Object.class);
+ o = mapper.readValue((InputStream)stream.toJava(InputStream.class), Object.class);
} else {
throw ruby.newArgumentError("Unsupported source. This method accepts String or IO");
}
- return (RubyObject)JavaUtil.convertJavaToRuby(ruby, o);
+ return RubyUtils.rubyObject(ruby, o);
}
catch (JsonProcessingException e) {
throw ParseError.newParseError(ruby, e.getLocalizedMessage());
}
catch (IOException e) {
throw ruby.newIOError(e.getLocalizedMessage());
}
}
+ // serialize
@JRubyMethod(module = true, name = {"generate", "dump"}, required = 1)
public static IRubyObject generate(ThreadContext context, IRubyObject self, IRubyObject arg) {
Ruby ruby = context.getRuntime();
Object obj = arg.toJava(Object.class);
try {
- String s = mapper.writeValueAsString(obj);
- return ruby.newString(s);
+ String s = mappers.get("raw").writeValueAsString(obj);
+ return RubyUtils.rubyString(ruby, s);
}
catch (JsonProcessingException e) {
throw ParseError.newParseError(ruby, e.getLocalizedMessage());
}
catch (IOException e) {