From 1f8f1a2f245876e43ad1291fb2c1db7fe516fbd9 Mon Sep 17 00:00:00 2001 From: Neil Sanchala Date: Thu, 23 Feb 2012 20:10:06 -0800 Subject: [PATCH 1/2] fix issue with Either deserialization with case classes EitherDeserializer was reusing a JsonParser first when it attempted to parse the Left, then if that failed and it tried to parse the Right. If the Left and Right sides look similar enough that the nextToken method was ever called on the parser, then the parsing of the Right could fail. --- .../jerkson/deser/EitherDeserializer.scala | 8 ++++- .../jerkson/tests/EitherSupportSpec.scala | 33 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/test/scala/com/codahale/jerkson/tests/EitherSupportSpec.scala diff --git a/src/main/scala/com/codahale/jerkson/deser/EitherDeserializer.scala b/src/main/scala/com/codahale/jerkson/deser/EitherDeserializer.scala index 75ab212..23b2916 100644 --- a/src/main/scala/com/codahale/jerkson/deser/EitherDeserializer.scala +++ b/src/main/scala/com/codahale/jerkson/deser/EitherDeserializer.scala @@ -17,7 +17,13 @@ class EitherDeserializer(config: DeserializationConfig, try { Left(tp.getCodec.readValue[Object](tp, javaType.containedType(0))) } catch { - case _ => Right(tp.getCodec.readValue[Object](tp, javaType.containedType(1))) + case _ => { + // We don't want to reuse the same parser that was used in the + // try-block, as the read there may have used nextToken() and advanced + // us past the point where we expect to be. + val tpRight = new TreeTraversingParser(node, jp.getCodec) + Right(tpRight.getCodec.readValue[Object](tpRight, javaType.containedType(1))) + } } } } diff --git a/src/test/scala/com/codahale/jerkson/tests/EitherSupportSpec.scala b/src/test/scala/com/codahale/jerkson/tests/EitherSupportSpec.scala new file mode 100644 index 0000000..2560504 --- /dev/null +++ b/src/test/scala/com/codahale/jerkson/tests/EitherSupportSpec.scala @@ -0,0 +1,33 @@ +package com.codahale.jerkson.tests + +import com.codahale.jerkson.Json._ +import com.codahale.simplespec.Spec +import com.codahale.jerkson.ParsingException +import org.codehaus.jackson.node.IntNode +import org.junit.Test + +class EitherSupportSpec extends Spec { + class `An Either of two case classes` { + @Test def `is parseable when the Left is used` = { + val e = parse[Either[CaseClassWithArrays, CaseClass]]("""{"one": "a", "two": [ "b", "c" ], "three": [ 0, 1 ]}""") + + e.isLeft.must(be(true)) + + val c = e.left.get + c.one.must(be("a")) + c.two.must(be(Array[String]("b", "c"))) + c.three.must(be(Array[Int](0, 1))) + } + + @Test def `is parseable when the Right is used` = { + val e = parse[Either[CaseClass, CaseClassWithArrays]]("""{"one": "a", "two": [ "b", "c" ], "three": [ 0, 1 ]}""") + + e.isRight.must(be(true)) + + val c = e.right.get + c.one.must(be("a")) + c.two.must(be(Array[String]("b", "c"))) + c.three.must(be(Array[Int](0, 1))) + } + } +} From 5fa4fd02068f385ea4be411a3a5c0f3b0edc7d70 Mon Sep 17 00:00:00 2001 From: kristian Date: Wed, 7 Mar 2012 09:39:37 +1000 Subject: [PATCH 2/2] Add support for parsing null values inside JSON arrays --- .../scala/com/codahale/jerkson/deser/JValueDeserializer.scala | 1 + .../scala/com/codahale/jerkson/tests/ASTTypeSupportSpec.scala | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/main/scala/com/codahale/jerkson/deser/JValueDeserializer.scala b/src/main/scala/com/codahale/jerkson/deser/JValueDeserializer.scala index b753339..00e963c 100644 --- a/src/main/scala/com/codahale/jerkson/deser/JValueDeserializer.scala +++ b/src/main/scala/com/codahale/jerkson/deser/JValueDeserializer.scala @@ -16,6 +16,7 @@ class JValueDeserializer(factory: TypeFactory, klass: Class[_]) extends JsonDese } val value = jp.getCurrentToken match { + case JsonToken.VALUE_NULL => JNull case JsonToken.VALUE_NUMBER_INT => JInt(BigInt(jp.getText)) case JsonToken.VALUE_NUMBER_FLOAT => JFloat(jp.getDoubleValue) case JsonToken.VALUE_STRING => JString(jp.getText) diff --git a/src/test/scala/com/codahale/jerkson/tests/ASTTypeSupportSpec.scala b/src/test/scala/com/codahale/jerkson/tests/ASTTypeSupportSpec.scala index 95e1040..5efd438 100644 --- a/src/test/scala/com/codahale/jerkson/tests/ASTTypeSupportSpec.scala +++ b/src/test/scala/com/codahale/jerkson/tests/ASTTypeSupportSpec.scala @@ -61,6 +61,10 @@ class ASTTypeSupportSpec extends Spec { @Test def `is parsable from a JSON null as a JValue` = { parse[JValue]("null").must(be(JNull)) } + + @Test def `is parsable from an embedded JSON null as a JValue` = { + parse[JValue]("[null]").must(be(JArray(List(JNull)))) + } } class `An AST.JBoolean` {