Skip to content

Instantly share code, notes, and snippets.

@rajish
Created June 29, 2012 11:51
Show Gist options
  • Save rajish/3017536 to your computer and use it in GitHub Desktop.
Save rajish/3017536 to your computer and use it in GitHub Desktop.
scalaxb generated code MongoDB conversion helper - a specific case
package models.util
import javax.xml.datatype.{XMLGregorianCalendar}
import javax.xml.namespace.QName
import com.mongodb.casbah.commons.conversions.MongoConversionHelper
import org.bson.{BSON, Transformer}
import scalaxb._
import models._
import play.api._
import com.novus.salat._
import com.novus.salat.global._
object RegisterXMLStandardTypesSerializer extends XMLStandardTypesHelper {
def apply(): Unit = super.register()
}
object DeregisterXMLStandardTypesSerializer extends XMLStandardTypesHelper {
def apply(): Unit = super.unregister()
}
object fieldsSeq{
def apply[T : ClassManifest](aggregate: T) = {
type FT = java.lang.Object
val seq = classManifest[T].erasure.getFields().map(field => field.get(aggregate)).foldRight(Seq[FT]())(_ +: _)
seq.asInstanceOf[AnyRef]
}
}
trait XMLStandardTypesHelper extends MongoConversionHelper {
private val transformer = new Transformer {
Logger.debug("XMLStandardTypesHelper convert")
def transformSeq[X : Manifest](s: X): AnyRef = {
s match {
case cz: Seq[CzType] => grater[CzTypeSeq].asDBObject(CzTypeSeq(coll = cz))
case cz: Seq[CzZmianyType] => grater[CzZmianyTypeSeq].asDBObject(CzZmianyTypeSeq(coll = cz))
case _ => s.asInstanceOf[AnyRef]
}
}
def transformField(d: DataRecord[Any], indent: Int = 0): AnyRef = {
// Logger.debug("XMLStandardTypesHelper matched DataRecord[Any] = " + " " * indent + "(" + d.key + " -> " + d.value + ")")
d.value match {
case c: XMLGregorianCalendar => c.toGregorianCalendar.getTime.asInstanceOf[AnyRef]
case cz: CzesciType => transformSeq(fieldsSeq(cz))
case zm: ZmianyType => transformSeq(fieldsSeq(zm))
case dr: DataRecord[Any] => transformField(dr, indent + 1)
case _ => d.value.asInstanceOf[AnyRef]
}
}
def transform(o: AnyRef): AnyRef = o match {
case d: DataRecord[Any] => transformField(d)
case _ => o
}
}
override def register() = {
BSON.addEncodingHook(classOf[DataRecord[Any]], transformer)
super.register()
}
override def unregister() = {
BSON.removeEncodingHooks(classOf[DataRecord[Any]])
super.unregister()
}
}
package test
import com.mongodb.casbah.Imports._
import com.novus.salat.dao.{ModelCompanion, SalatDAO}
import java.io._
import models._
import models.util._
import org.apache.commons.net.ftp._
import org.scala_tools.time.Imports._
import org.specs2.mutable._
import play.api._
import play.api.Play.current
import play.api.test._
import play.api.test.Helpers._
import scala.sys.process._
import scalaxb._
import zpProtocol._
class XMLImportSpec extends Specification {
override def is = args(sequential = true) ^ super.is
val log = play.api.Logger
"Database" should {
"be filled with data from XML files" in new FakeApp() {
"download" must beAWritablePath
val dnloads = tree(new File("download")).toArray
def imported = for {
f <- dnloads if (f.isFile && f.getName.endsWith(".xml"))
nodes = xml.XML.loadFile("download/" + f.getName)
parsed = scalaxb.fromXML[ZpBaseType](nodes)
} yield parsed
var cnt = 0
for(rec <- imported) {
rec.zpbasetypeoption must beAnInstanceOf[Seq[Any]]
PublicOrder.insert(rec) must beSome
MongoConnection()(play.api.Play.configuration.getString("mongodb.default.db").get).getLastError.get("err") must beNull
cnt += 1
}
cnt aka "import iterations" must_== imported.length
PublicOrder.collection aka "the imported collection" must haveSize(imported.length)
}
}
step (DeregisterXMLStandardTypesSerializer())
}
trait FakeApp extends Around {
val db_name = "offers_db_test"
def mongoTestDatabase() = Map("mongodb.default.db" -> db_name,
"source.ftp" -> "ftp.uzp.gov.pl")
object FakeApp extends FakeApplication(additionalConfiguration = mongoTestDatabase())
val Some(ftpAddr) = FakeApp.configuration.getString("source.ftp")
def around[T <% org.specs2.execute.Result](test: =>T) = running(FakeApplication(additionalConfiguration = mongoTestDatabase())) {
test // run tests inside a fake application
}
def tree(root: File, skipHidden: Boolean = true): Stream[File] =
if (!root.exists || (skipHidden && root.isHidden)) Stream.empty
else root #:: (
root.listFiles match {
case null => Stream.empty
case files => files.toStream.flatMap(tree(_, skipHidden))
})
}
package models
import com.mongodb.casbah.Imports._
import com.novus.salat._
import com.novus.salat.dao.{ModelCompanion, SalatDAO}
import com.novus.salat.annotations._
import com.novus.salat.global._
import org.scala_tools.time.Imports._
import play.api.Play.current
import se.radley.plugin.salat._
case class CzTypeSeq(@Key("_id") id: ObjectId = new ObjectId, coll: Seq[CzType])
case class CzZmianyTypeSeq(@Key("_id") id: ObjectId = new ObjectId, coll: Seq[CzZmianyType])
object PublicOrder extends ModelCompanion[ZpBaseType, ObjectId] {
val collection = MongoConnection()(play.api.Play.configuration.getString("mongodb.default.db").get)("pub_orders")
val dao = new SalatDAO[ZpBaseType, ObjectId](collection = collection){
collection.ensureIndex(MongoDBObject("pozycja" -> 1, "data_publikacji" -> 1), "bid", unique = true)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment