Skip to content

Instantly share code, notes, and snippets.

@ssuravarapu
Created August 18, 2010 23:35
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ssuravarapu/536539 to your computer and use it in GitHub Desktop.
Save ssuravarapu/536539 to your computer and use it in GitHub Desktop.
object UserManagementService extends RestHelper {
....
serveJx {
case Get("api" :: "user" :: id :: _, _) => Full(loadUser(id))
}
}
trait Convertable {
def toXml: Node
def toJson: JValue
}
implicit def cvt: JxCvtPF[Convertable] = {
case (JsonSelect, c, _) => c.toJson
case (XmlSelect, c, _) => c.toXml
}
trait RestHelper extends LiftRules.DispatchPF {
...
/**
* A function that chooses JSON or XML based on the request..
* Use with serveType
*/
implicit def jxSel(req: Req): Box[JsonXmlSelect] =
if (jsonResponse_?(req)) Full(JsonSelect)
else if (xmlResponse_?(req)) Full(XmlSelect)
else None
}
----------------------------------------------------------------
object UserManagementService extends RestHelper {
...
override implicit def jxSel(req: Req): Box[JsonXmlSelect] = {
val prefs = ClientMediaPreference orderedList (req.headers("accept"))
val preferredMediaType = prefs(0).mediaType + "/" + prefs(0).mediaSubType
if(preferredMediaType == "text/xml" || preferredMediaType == "application/xml") Full(XmlSelect)
else if (preferredMediaType == "application/json") Full(JsonSelect)
else None
}
}
case class User (@Column("first_name") val firstName: String, @Column("last_name") val lastName:String, val email:String)
extends UserManagementDB with Convertable {
....
def toXml():Node = {
<user>
<id>{this.id}</id>
<firstName>{this.firstName}</firstName>
<lastName>{this.lastName}</lastName>
<email>{this.email}</email>
</user>
}
def toJson():JValue = {
Extraction.decompose(this)
}
}
object UserManagementService extends RestHelper {
...
override implicit def jxSel(req: Req): Box[JsonXmlSelect] = {
val prefs = ClientMediaPreference orderedList (req.headers("accept"))
val preferredMediaType = prefs(0).mediaType + "/" + prefs(0).mediaSubType
if(preferredMediaType == "text/xml" || preferredMediaType == "application/xml") Full(XmlSelect)
else if (preferredMediaType == "application/json") Full(JsonSelect)
else None
}
}
object ClientMediaPreference {
def orderedList(acceptHeader:List[String]):List[Media] = {
acceptHeader.size match {
case 0 => Media("application", "xml", 1.0f) :: List() // XML is the default (this can be customized somewhere, if no Accept Header)
case _ => parseAcceptHeader(acceptHeader)
}
}
private def parseAcceptHeader(acceptHeader:List[String]): List[Media] = {
val mediaPrefs = acceptHeader(0) split (",") map (_.trim)
val acceptHeaderVals = for{
pref <- mediaPrefs
val media = parseMime(pref)
} yield media
acceptHeaderVals.toList.sortWith((e1, e2) => e1.qualityFactor > e2.qualityFactor)
}
private def parseMime(header:String):Media = {
var q = 1.0f //defaults to 1.0
val parts = header split(";")
val typeSubType = parts(0) split("/")
if (parts.length == 2) {
q = (parts(1) split("="))(1).toFloat
}
Media(typeSubType(0), typeSubType(1), q)
}
}
case class Media(mediaType:String, mediaSubType:String, qualityFactor:Float) {
override def toString:String = {
"Media[" + mediaType + "/" + mediaSubType + "; q=" + qualityFactor + "]"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment