/** * This was something I explored today. * The approach is fundamentally flawed for a couple of reasons. * * 1. play JSON serializes dates to strings, * but they are better represented as timestamps or ISODates in mongo. * * 2. ObjectId's cannot be round-tripped, since they turn into JSON * strings on the way out. * * There are probably further issues as well... */ package dao.mongodb import play.api.libs.json._ import com.mongodb.casbah.Implicits._ import com.mongodb.BasicDBList import com.mongodb.DBObject import com.mongodb.casbah.commons.MongoDBObject import com.mongodb.casbah.commons.MongoDBList import org.bson.types.ObjectId object JsonUtil { def toMongoDBObject(obj: JsObject): DBObject = { MongoDBObject { obj.fields.toList.map { case (key, value) => key -> toMongo(value) } } } def toMongoDBList(list: JsArray): BasicDBList = { MongoDBList.concat { list.value.map { value => toMongo(value) } } } def toMongo(json: JsValue): Any = json match { case list: JsArray => toMongoDBList(list) case JsBoolean(value) => value case JsNull => null case JsNumber(value) => value.toDouble case obj: JsObject => toMongoDBObject(obj) case JsString(value) => value case undefined: JsUndefined => sys.error(undefined.toString) } def fromMongoDBObject(obj: MongoDBObject): JsObject = { JsObject(obj.toSeq.map { case (key, value) => key -> fromMongo(value) }) } def fromMongoDBList(list: MongoDBList): JsArray = { JsArray(list.map(fromMongo)) } private def fromMongo(a: Any): JsValue = a match { case id: ObjectId => JsString(id.toString) case list: BasicDBList => fromMongoDBList(list) case obj: DBObject => fromMongoDBObject(obj) case long: Long => JsNumber(long) case int: Int => JsNumber(int) case float: Float => JsNumber(float) case double: Double => JsNumber(double) case decimal: java.math.BigDecimal => JsNumber(decimal) case decimal: scala.BigDecimal => JsNumber(decimal) case string: String => JsString(string) case boolean: Boolean => JsBoolean(boolean) case null => JsNull } }