PageRenderTime 25ms CodeModel.GetById 0ms RepoModel.GetById 1ms app.codeStats 0ms

/datastore/src/main/scala/org/sgine/datastore/mongodb/converter/DataObjectConverter.scala

https://code.google.com/p/sgine/
Scala | 108 lines | 93 code | 12 blank | 3 comment | 13 complexity | 290f63940105e6d80e60a7adad77e53d MD5 | raw file
  1. package org.sgine.datastore.mongodb.converter
  2. import org.sgine.EnumEntry
  3. import org.bson.types.ObjectId
  4. import com.mongodb.{BasicDBList, DBObject}
  5. import annotation.tailrec
  6. import com.mongodb.casbah.commons.{MongoDBList, MongoDBListBuilder, MongoDBObject}
  7. import collection.mutable.ListBuffer
  8. import com.mongodb.casbah.commons.Implicits._
  9. import java.util.{Calendar, UUID}
  10. /**
  11. * @author Matt Hicks <mhicks@sgine.org>
  12. */
  13. trait DataObjectConverter {
  14. def fromDBObject(db: MongoDBObject): AnyRef
  15. def toDBObject(obj: AnyRef): DBObject
  16. }
  17. object DataObjectConverter {
  18. private var map = Map.empty[Class[_], DataObjectConverter]
  19. def fromDBObject[T](db: MongoDBObject) = {
  20. val clazz = Class.forName(db.as[String]("class"))
  21. val converter = findConverter(clazz)
  22. converter.fromDBObject(db).asInstanceOf[T]
  23. }
  24. def toDBObject(obj: AnyRef) = {
  25. val converter = findConverter(obj.getClass)
  26. converter.toDBObject(obj)
  27. }
  28. private def findConverter(clazz: Class[_]) = {
  29. if (!map.contains(clazz)) {
  30. synchronized {
  31. if (!map.contains(clazz)) {
  32. val converter = if (classOf[EnumEntry[_]].isAssignableFrom(clazz)) {
  33. EnumDataObjectConverter
  34. } else if (classOf[Calendar].isAssignableFrom(clazz)) {
  35. CalendarDataObjectConverter
  36. } else if (classOf[Map[_, _]].isAssignableFrom(clazz)) {
  37. MapDataObjectConverter
  38. } else if (classOf[java.util.Map[_, _]].isAssignableFrom(clazz)) {
  39. MapDataObjectConverter
  40. } else {
  41. new ReflectiveDataObjectConverter(clazz)
  42. }
  43. map += clazz -> converter
  44. }
  45. }
  46. }
  47. map(clazz)
  48. }
  49. def toDBValue(obj: Any) = obj match {
  50. case objectId: ObjectId => objectId
  51. case uuid: UUID => uuid
  52. case seq: Seq[_] => toDBList(seq)
  53. case s: String => s
  54. case b: Boolean => b
  55. case b: Byte => b
  56. case c: Char => c
  57. case i: Int => i
  58. case l: Long => l
  59. case f: Float => f
  60. case d: Double => d
  61. case null => null
  62. case obj: AnyRef => toDBObject(obj)
  63. }
  64. def fromDBValue(obj: Any) = obj match {
  65. case objectId: ObjectId => objectId
  66. case uuid: UUID => uuid
  67. case dbList: BasicDBList => fromDBList(dbList)
  68. case s: String => s
  69. case b: Boolean => b
  70. case b: Byte => b
  71. case c: Char => c
  72. case i: Int => i
  73. case l: Long => l
  74. case f: Float => f
  75. case d: Double => d
  76. case null => null
  77. case obj: DBObject => fromDBObject(obj)
  78. }
  79. @tailrec
  80. private def toDBList(seq: Seq[_], listBuilder: MongoDBListBuilder = MongoDBList.newBuilder): BasicDBList = {
  81. if (seq.nonEmpty) {
  82. val head = toDBValue(seq.head.asInstanceOf[AnyRef])
  83. listBuilder += head
  84. toDBList(seq.tail, listBuilder)
  85. } else {
  86. listBuilder.result()
  87. }
  88. }
  89. private def fromDBList(dbList: BasicDBList): List[Any] = {
  90. val buffer = new ListBuffer[Any]
  91. for (v <- dbList) {
  92. buffer += fromDBValue(v)
  93. }
  94. buffer.toList
  95. }
  96. }