Skip to content
Browse files

well that was rough. add java array support. don't look too closely.

  • Loading branch information...
1 parent 32f9035 commit 40b2ac1551b7b3b2922db69b67c1f75adc4ace7f Robey Pointer committed Aug 22, 2010
View
66 src/main/scala/com/twitter/streamyj/StreamyUnpacker.scala
@@ -16,16 +16,22 @@ class StreamyUnpacker {
var ignoreExtraFields = false
def coerce[A, B](name: String, obj: A, cls: Class[B])(implicit manifest: Manifest[A]): B = {
- if (manifest.erasure == classOf[Long]) {
+ coerce(name, obj, manifest.erasure.asInstanceOf[Class[A]], cls)
+ }
+
+ def coerce[A, B](name: String, obj: A, objcls: Class[A], cls: Class[B]): B = {
+ if (objcls == classOf[Long] || objcls == classOf[java.lang.Long]) {
coerceLong(name, cls, obj.asInstanceOf[Long])
- } else if (manifest.erasure == classOf[Double]) {
+ } else if (objcls == classOf[Double]) {
coerceDouble(name, cls, obj.asInstanceOf[Double])
- } else if (manifest.erasure == classOf[String]) {
+ } else if (objcls == classOf[String]) {
coerceString(name, cls, obj.asInstanceOf[String])
- } else if (manifest.erasure == classOf[Boolean]) {
+ } else if (objcls == classOf[Boolean]) {
coerceBoolean(name, cls, obj.asInstanceOf[Boolean])
+ } else if (objcls == classOf[List[AnyRef]]) {
+ coerceList(name, cls, obj.asInstanceOf[List[AnyRef]])
} else {
- throw new JsonUnpackingException("foo")
+ throw new JsonUnpackingException("foo: " + objcls)
}
}
@@ -117,28 +123,64 @@ class StreamyUnpacker {
rv.asInstanceOf[T]
}
+ private def coerceList[T, A <: AnyRef](name: String, cls: Class[T], list: List[A]): T = {
+ val rv: Any = if (cls == classOf[Seq[A]]) {
+ list.toSeq
+ } else if (cls == classOf[List[A]]) {
+ list
+ } else if (cls.isArray) {
+ // eww.
+ val coercedItems = list.map { item => coerce(name, item, item.getClass.asInstanceOf[Class[Any]], cls.getComponentType) }
+ val array = Array.newInstance(cls.getComponentType, list.size)
+ for (i <- 0 until list.size) {
+ Array.set(array, i, coercedItems(i))
+ }
+ array
+ } else {
+ throw new JsonUnpackingException(name, cls, "list")
+ }
+ rv.asInstanceOf[T]
+ }
+
def setField[T](obj: T, field: Field, streamy: Streamy) {
streamy.next() match {
case ValueLong(x) => field.set(obj, coerce(field.getName, x, field.getType))
case ValueDouble(x) => field.set(obj, coerce(field.getName, x, field.getType))
case ValueString(x) => field.set(obj, coerce(field.getName, x, field.getType))
case ValueFalse => field.set(obj, coerce(field.getName, false, field.getType))
case ValueTrue => field.set(obj, coerce(field.getName, true, field.getType))
-// case StartArray => setArrayField(obj, field, getArray(streamy))
+ case StartArray => field.set(obj, coerce(field.getName, getArray(streamy), field.getType))
case x =>
throw new JsonUnpackingException("Unexpected token: " + x)
/*
case object StartArray extends StreamyToken
- case object EndArray extends StreamyToken
case object StartObject extends StreamyToken
- case object EndObject extends StreamyToken
case object ValueNull extends StreamyToken
*/
+ }
+ }
+
+ def getArray(streamy: Streamy) = {
+ val list = new mutable.ListBuffer[Any]
+ getArrayNext(streamy, list).toList
+ }
- // null
- // array, object
+ def getArrayNext(streamy: Streamy, list: mutable.ListBuffer[Any]): mutable.ListBuffer[Any] = {
+ streamy.next() match {
+ case EndArray => return list
+ case ValueLong(x) => list += x
+ case ValueDouble(x) => list += x
+ case ValueString(x) => list += x
+ case ValueFalse => list += false
+ case ValueTrue => list += true
+ case ValueNull => list += null
+ case StartArray => list += getArray(streamy)
+// case object StartObject extends StreamyToken
+ case x =>
+ throw new JsonUnpackingException("Unexpected token: " + x)
}
+ getArrayNext(streamy, list)
}
@throws(classOf[JsonProcessingException])
@@ -192,6 +234,6 @@ class StreamyUnpacker {
}
object StreamyUnpacker {
- def apply[T](s: String)(implicit manifest: Manifest[T]) =
- new StreamyUnpacker().unpackObject(new Streamy(s), manifest.erasure)
+ def apply[T](s: String)(implicit manifest: Manifest[T]): T =
+ new StreamyUnpacker().unpackObject(new Streamy(s), manifest.erasure.asInstanceOf[Class[T]])
}
View
17 src/test/scala/com/twitter/streamyj/StreamyUnpackerSpec.scala
@@ -93,5 +93,22 @@ object StreamyUnpackerSpec extends Specification {
StreamyUnpacker[CryForMe]("""{"cry":false}""") mustEqual CryForMe(false)
StreamyUnpacker[CryForMe]("""{"cry":true}""") mustEqual CryForMe(true)
}
+
+ "object of arrays" in {
+ val data = """{"name":"Santa","grades":[95, 79, 88, 90]}"""
+
+ case class SeqGrades(name: String, grades: Seq[Int])
+ StreamyUnpacker[SeqGrades](data) mustEqual SeqGrades("Santa", List(95, 79, 88, 90).toSeq)
+
+ case class ListGrades(name: String, grades: List[Int])
+ StreamyUnpacker[ListGrades](data) mustEqual ListGrades("Santa", List(95, 79, 88, 90))
+
+ case class ArrayGrades(name: String, grades: Array[Int])
+ StreamyUnpacker[ArrayGrades](data).grades.toList mustEqual List(95, 79, 88, 90)
+
+ val data2 = """{"name":"Santa","friends":["Rudolph","Frosty"]}"""
+ case class ArrayFriends(name: String, friends: Array[String])
+ StreamyUnpacker[ArrayFriends](data2).friends.toList mustEqual List("Rudolph", "Frosty")
+ }
}
}

0 comments on commit 40b2ac1

Please sign in to comment.
Something went wrong with that request. Please try again.