Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Issue 1275 - Allow overriding of formats in MongoCaseClassField

  • Loading branch information...
commit 8069db87b10e929e534006ded60d74e738d47a8b 1 parent e546a9f
@eltimn eltimn authored
View
38 persistence/mongodb-record/src/main/scala/net/liftweb/mongodb/record/field/MongoCaseClassField.scala
@@ -11,10 +11,10 @@
* limitations under the License.
*/
-package net.liftweb
-package mongodb
-package record
-package field
+package net.liftweb
+package mongodb
+package record
+package field
import net.liftweb.record._
import net.liftweb.record.RecordHelpers.jvalueToJsExp
@@ -31,8 +31,10 @@ import net.liftweb.http.js.JsExp
class MongoCaseClassField[OwnerType <: Record[OwnerType],CaseType](rec: OwnerType)( implicit mf: Manifest[CaseType]) extends Field[CaseType, OwnerType] with MandatoryTypedField[CaseType] with MongoFieldFlavor[CaseType] {
-
- implicit val formats = net.liftweb.json.DefaultFormats
+
+ // override this for custom formats
+ def formats: Formats = DefaultFormats
+ implicit lazy val _formats = formats
override type MyType = CaseType
@@ -60,7 +62,7 @@ class MongoCaseClassField[OwnerType <: Record[OwnerType],CaseType](rec: OwnerTyp
val jvalue = JObjectParser.serialize(dbo)
setFromJValue(jvalue)
}
-
+
override def setFromString(in: String): Box[CaseType] = {
Helpers.tryo{ JsonParser.parse(in).extract[CaseType] }
}
@@ -76,22 +78,24 @@ class MongoCaseClassField[OwnerType <: Record[OwnerType],CaseType](rec: OwnerTyp
}
class MongoCaseClassListField[OwnerType <: Record[OwnerType],CaseType](rec: OwnerType)( implicit mf: Manifest[CaseType]) extends Field[List[CaseType], OwnerType] with MandatoryTypedField[List[CaseType]] with MongoFieldFlavor[List[CaseType]] {
-
- implicit val formats = net.liftweb.json.DefaultFormats
-
+
+ // override this for custom formats
+ def formats: Formats = DefaultFormats
+ implicit lazy val _formats = formats
+
override type MyType = List[CaseType]
-
+
def owner = rec
def asXHtml = Text(value.toString)
-
+
def toForm: Box[NodeSeq] = Empty
override def defaultValue: MyType = Nil
override def optional_? = true
-
+
def asJValue = JArray(value.map(v => Extraction.decompose(v)))
-
+
def setFromJValue(jvalue: JValue): Box[MyType] = jvalue match {
case JArray(contents) => setBox(Full(contents.flatMap(s => Helpers.tryo[CaseType]{ s.extract[CaseType] })))
case _ => setBox(Empty)
@@ -99,12 +103,12 @@ class MongoCaseClassListField[OwnerType <: Record[OwnerType],CaseType](rec: Owne
def asDBObject: DBObject = {
val dbl = new BasicDBList
-
+
asJValue match {
- case JArray(list) =>
+ case JArray(list) =>
list.foreach(v => dbl.add(JObjectParser.parse(v.asInstanceOf[JObject])))
}
-
+
dbl
}
View
23 persistence/mongodb-record/src/test/scala/net/liftweb/mongodb/record/Fixtures.scala
@@ -22,7 +22,8 @@ package fixtures
import field._
import common.{Box, Empty, Failure, Full}
-import json.ext.JsonBoxSerializer
+import json._
+import json.ext.{EnumSerializer, JsonBoxSerializer}
import http.SHtml
import util.FieldError
@@ -243,6 +244,10 @@ class MongoFieldTypeTestRecord private () extends MongoRecord[MongoFieldTypeTest
object mandatoryUUIDField extends UUIDField(this)
object legacyOptionalUUIDField extends UUIDField(this) { override def optional_? = true }
+ object mandatoryMongoCaseClassField extends MongoCaseClassField[MongoFieldTypeTestRecord, MongoCaseClassTestObject](this) {
+ override def formats = owner.meta.formats
+ }
+
override def equals(other: Any): Boolean = other match {
case that: MongoFieldTypeTestRecord =>
this.id.value == that.id.value &&
@@ -251,7 +256,8 @@ class MongoFieldTypeTestRecord private () extends MongoRecord[MongoFieldTypeTest
this.mandatoryObjectIdField.value == that.mandatoryObjectIdField.value &&
this.mandatoryPatternField.value.pattern == that.mandatoryPatternField.value.pattern &&
this.mandatoryPatternField.value.flags == that.mandatoryPatternField.value.flags &&
- this.mandatoryUUIDField.value == that.mandatoryUUIDField.value
+ this.mandatoryUUIDField.value == that.mandatoryUUIDField.value &&
+ this.mandatoryMongoCaseClassField.value == that.mandatoryMongoCaseClassField.value
case _ => false
}
@@ -259,7 +265,7 @@ class MongoFieldTypeTestRecord private () extends MongoRecord[MongoFieldTypeTest
}
object MongoFieldTypeTestRecord extends MongoFieldTypeTestRecord with MongoMetaRecord[MongoFieldTypeTestRecord] {
- override def formats = allFormats
+ override def formats = allFormats + new EnumSerializer(MyTestEnum)
}
class PasswordTestRecord private () extends MongoRecord[PasswordTestRecord] with ObjectIdPk[PasswordTestRecord] {
@@ -269,7 +275,7 @@ class PasswordTestRecord private () extends MongoRecord[PasswordTestRecord] with
}
object PasswordTestRecord extends PasswordTestRecord with MongoMetaRecord[PasswordTestRecord]
-case class MongoCaseClassTestObject(intField: Int, stringField: String)
+case class MongoCaseClassTestObject(intField: Int, stringField: String, enum: MyTestEnum.Value)
class ListTestRecord private () extends MongoRecord[ListTestRecord] with UUIDPk[ListTestRecord] {
def meta = ListTestRecord
@@ -283,7 +289,9 @@ class ListTestRecord private () extends MongoRecord[ListTestRecord] with UUIDPk[
object mandatoryMongoJsonObjectListField extends MongoJsonObjectListField(this, TypeTestJsonObject)
object legacyOptionalMongoJsonObjectListField extends MongoJsonObjectListField(this, TypeTestJsonObject) { override def optional_? = true }
- object mongoCaseClassListField extends MongoCaseClassListField[ListTestRecord, MongoCaseClassTestObject](this)
+ object mongoCaseClassListField extends MongoCaseClassListField[ListTestRecord, MongoCaseClassTestObject](this) {
+ override def formats = owner.meta.formats
+ }
// TODO: More List types
@@ -292,14 +300,15 @@ class ListTestRecord private () extends MongoRecord[ListTestRecord] with UUIDPk[
this.id.value == that.id.value &&
this.mandatoryStringListField.value == that.mandatoryStringListField.value &&
this.mandatoryIntListField.value == that.mandatoryIntListField.value &&
- this.mandatoryMongoJsonObjectListField.value == that.mandatoryMongoJsonObjectListField.value
+ this.mandatoryMongoJsonObjectListField.value == that.mandatoryMongoJsonObjectListField.value &&
+ this.mongoCaseClassListField.value == that.mongoCaseClassListField.value
case _ => false
}
def dirtyFields = this.allFields.filter(_.dirty_?)
}
object ListTestRecord extends ListTestRecord with MongoMetaRecord[ListTestRecord] {
- override def formats = allFormats
+ override def formats = allFormats + new EnumSerializer(MyTestEnum)
}
class MapTestRecord private () extends MongoRecord[MapTestRecord] with StringPk[MapTestRecord] {
View
2  persistence/mongodb-record/src/test/scala/net/liftweb/mongodb/record/MongoFieldSpec.scala
@@ -323,7 +323,7 @@ object MongoFieldSpec extends Specification("MongoField Specification") with Mon
"MongoCaseClassListField" should {
"setFromAny a List" in {
val rec = ListTestRecord.createRecord
- val lst = List(MongoCaseClassTestObject(1,"str1"))
+ val lst = List(MongoCaseClassTestObject(1,"str1", MyTestEnum.THREE))
rec.mongoCaseClassListField.setFromAny(lst)
rec.mongoCaseClassListField.value must_== lst
}
View
22 persistence/mongodb-record/src/test/scala/net/liftweb/mongodb/record/MongoRecordSpec.scala
@@ -37,17 +37,17 @@ import com.mongodb._
* Systems under specification for MongoRecord.
*/
object MongoRecordSpec extends Specification("MongoRecord Specification") with MongoTestKit {
-
import fixtures._
"MongoRecord field introspection" should {
checkMongoIsRunning
val rec = MongoFieldTypeTestRecord.createRecord
- val allExpectedFieldNames: List[String] = "_id" :: (for {
- typeName <- "Date JsonObject ObjectId Pattern UUID".split(" ")
- flavor <- "mandatory legacyOptional".split(" ")
- } yield flavor + typeName + "Field").toList
+ val allExpectedFieldNames: List[String] = "_id" :: "mandatoryMongoCaseClassField" ::
+ (for {
+ typeName <- "Date JsonObject ObjectId Pattern UUID".split(" ")
+ flavor <- "mandatory legacyOptional".split(" ")
+ } yield flavor + typeName + "Field").toList
"introspect only the expected fields" in {
rec.fields().map(_.name).filterNot(allExpectedFieldNames.contains(_)) must_== Nil
@@ -194,6 +194,7 @@ object MongoRecordSpec extends Specification("MongoRecord Specification") with M
.mandatoryObjectIdField(ObjectId.get)
.mandatoryPatternField(Pattern.compile("^Mo", Pattern.CASE_INSENSITIVE))
.mandatoryUUIDField(UUID.randomUUID)
+ .mandatoryMongoCaseClassField(MongoCaseClassTestObject(1,"str",MyTestEnum.TWO))
val mfttrJson =
("_id" -> ("$oid" -> mfttr.id.toString)) ~
@@ -206,13 +207,14 @@ object MongoRecordSpec extends Specification("MongoRecord Specification") with M
("mandatoryPatternField" -> (("$regex" -> mfttr.mandatoryPatternField.value.pattern) ~ ("$flags" -> mfttr.mandatoryPatternField.value.flags))) ~
("legacyOptionalPatternField" -> (None: Option[JObject])) ~
("mandatoryUUIDField" -> ("$uuid" -> mfttr.mandatoryUUIDField.value.toString)) ~
- ("legacyOptionalUUIDField" -> (None: Option[JObject]))
+ ("legacyOptionalUUIDField" -> (None: Option[JObject])) ~
+ ("mandatoryMongoCaseClassField" -> ("intField" -> 1) ~ ("stringField" -> "str") ~ ("enum" -> 1))
val ltr = ListTestRecord.createRecord
.mandatoryStringListField(List("abc", "def", "ghi"))
.mandatoryIntListField(List(4, 5, 6))
.mandatoryMongoJsonObjectListField(List(TypeTestJsonObject(1, "jsonobj1", Map("x" -> "1")), TypeTestJsonObject(2, "jsonobj2", Map("x" -> "2"))))
- .mongoCaseClassListField(List(MongoCaseClassTestObject(1,"str")))
+ .mongoCaseClassListField(List(MongoCaseClassTestObject(1,"str",MyTestEnum.TWO)))
val ltrJson =
("_id" -> ("$uuid" -> ltr.id.toString)) ~
@@ -226,7 +228,7 @@ object MongoRecordSpec extends Specification("MongoRecord Specification") with M
)) ~
("legacyOptionalMongoJsonObjectListField" -> List[JObject]()) ~
("mongoCaseClassListField" -> List(
- ("intField" -> 1) ~ ("stringField" -> "str")
+ ("intField" -> 1) ~ ("stringField" -> "str") ~ ("enum" -> 1)
))
val mtr = MapTestRecord.createRecord
@@ -685,7 +687,7 @@ object MongoRecordSpec extends Specification("MongoRecord Specification") with M
fttr.legacyOptionalStringField(Empty)
fttr.legacyOptionalStringField.dirty_? must_== true
- fttr.dirtyFields.length must_== 7
+ fttr.dirtyFields.length must_== 9
fttr.update
fttr.dirtyFields.length must_== 0
@@ -792,7 +794,7 @@ object MongoRecordSpec extends Specification("MongoRecord Specification") with M
ltr.mandatoryMongoJsonObjectListField(List(TypeTestJsonObject(1, "jsonobj1", Map("x" -> "1")), TypeTestJsonObject(2, "jsonobj2", Map("x" -> "2"))))
ltr.mandatoryMongoJsonObjectListField.dirty_? must_== true
- ltr.mongoCaseClassListField(List(MongoCaseClassTestObject(1,"str")))
+ ltr.mongoCaseClassListField(List(MongoCaseClassTestObject(1,"str",MyTestEnum.TWO)))
ltr.mongoCaseClassListField.dirty_? must_== true
ltr.dirtyFields.length must_== 4
View
6 persistence/mongodb/src/main/scala/net/liftweb/mongodb/JObjectParser.scala
@@ -36,10 +36,12 @@ object JObjectParser extends SimpleInjector {
*
* <code>JObjectParser.stringProcessor.default.set((s: String) => s)</code>
*/
- val stringProcessor = new Inject(() => (s: String) => {
+ val stringProcessor = new Inject(() => defaultStringProcessor _) {}
+
+ def defaultStringProcessor(s: String): Object = {
if (ObjectId.isValid(s)) new ObjectId(s)
else s
- }) {}
+ }
/*
* Parse a JObject into a DBObject
View
16 persistence/mongodb/src/test/scala/net/liftweb/mongodb/JObjectParserSpec.scala
@@ -45,14 +45,14 @@ object JObjectParserSpec extends Specification("JObjectParser Specification") {
}
}
"not convert strings to ObjectId when configured not to" in {
- JObjectParser.stringProcessor.default.set((s: String) => s)
-
- val (oid, dbo) = buildTestData
- val xval = tryo(dbo.get("x").asInstanceOf[String])
-
- xval must notBeEmpty
- xval.foreach { x =>
- x must_== oid.toString
+ JObjectParser.stringProcessor.doWith((s: String) => s) {
+ val (oid, dbo) = buildTestData
+ val xval = tryo(dbo.get("x").asInstanceOf[String])
+
+ xval must notBeEmpty
+ xval.foreach { x =>
+ x must_== oid.toString
+ }
}
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.