Skip to content
Max Afonov edited this page Jan 12, 2011 · 2 revisions

Most of Salat's code is for internal use only and encapsulated away from the programmer who's using Salat in their project. There are however a few points of interest where rubber meets road, so to speak.

Aside: Please get past any class or method names in this project that don't make sense. If you'd like to propose a better name (or naming convention for other components that comprise Salat), please fork the code, make your changes, and submit a pull request.

Context trait

Certain data structures required in the course of Salat's operations must be shared between a number of disparate (de)serializers. The most obvious shared data structure is a map of Class[_] to Grater[_]: a cache of sorts, which is useful in the course of discovering a Grater instance capable of handling objects of a certain case class. Graters routinely attempt to discover each other. This is an essential part of Salat's ability to work with arbitrarily nested graphs of embedded objects.

An object mixing in the Context trait is where Salat expects to store and find such shared data structures. A context is usually not an entry point through which Salat's functionality can be accessed. It is rather meant to be used as an implicit val which can be picked up by Salat's actual entry points.

For example, the grater[X] function (which you get when you import com.novus.salat._) expects to find an implicit Context in the call site's scope. Having a context which knows about all available Graters is useful because repeated requests for a Grater which has already been instantiated will return the same instance.

In general, almost all parts of Salat expect to have an implicit val of type Context somewhere in scope. This way, extensive configuration of Salat's behavior is possible. One such customization is the ability to turn off type hint generation at Context level. All Graters known to this context will refrain from producing any type hints in DBObject-s.

abstract class Grater

Salat is designed to perform only two operations for the call site, primarily because its users are expected to only want to do two things:

  • serialize instance of a case class (in other words, produce a corresponding DBObject instance)

  • deserialize a DBObject back into a properly constructed instance of some case class

Purpose and obtaining an instance

Grater is designed as the only exposed part of a graph of internal Salat objects that fully encapsulate all information necessary to perform serialization and deserialization of objects. In order to do anything with Salat, an instance of Grater should first be obtained.

The simplest and most common way of finding a Grater instance is by calling the grater[X] function. For example, given a case class Widget:

import com.novus.salat._

// Provides implicit Context instance. Don't import this if you
// have defined a custom Context in one of your own imports.
import com.novus.salat.global._

case class Widget(name: String)
val g = grater[Widget]

Of course, the above only works when the concrete case class is known at compile time. If you'd like to obtain a Grater programmatically when only a fully-qualified name of a class is available, you can call any of the lookup (return type Option[Grater[_]] or lookup_! (return type Grater[_]) methods in trait Context.

asDBObject

Two entry points are provided for this purpose by the Grater class: asDBObject and asObject.

As is probably obvious, you'd call asDBObject if you wanted to serialize an object. This method takes as its input a case class instance, and returns as its output a ready to insert into MongoDB DBObject.

asObject

The inverse operation, deserialization, is performed by calling asObject with a DBObject instance. Thanks to Casbah's convenient implicit conversions (which most users of Casbah should and do import), you shouldn't care whether you're passing in a real DBObject or Casbah's MongoDBObject.

In case of success, the method will return an instance of the same case class from which the DBObject was originally produced.

Clone this wiki locally