Skip to content
This repository has been archived by the owner on Jul 30, 2024. It is now read-only.

Commit

Permalink
Upgraded the Jaxb and Jackson marshallers
Browse files Browse the repository at this point in the history
  • Loading branch information
alexanderdean committed Apr 13, 2012
1 parent 97bacbe commit b1ef09a
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 23 deletions.
6 changes: 6 additions & 0 deletions src/main/scala/co/orderly/narcolepsy/Client.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ abstract class Client(
// Map resource slug names against the Representation subclasses required by this RESTful API
protected val resources: Api

// The marshaller
// protected val marshaller:

// The unmarshaller
// TODO

// -------------------------------------------------------------------------------------------------------------------
// You can override the following defaults in your NarcolepsyClient if you want
// -------------------------------------------------------------------------------------------------------------------
Expand Down
8 changes: 2 additions & 6 deletions src/main/scala/co/orderly/narcolepsy/Query.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ import java.util.UUID
import adapters._
import utils._

// TODO: remove these when we decouple specific unmarshallers from the Query engine
import marshallers.jackson.UnmarshalJson
import marshallers.jaxb.UnmarshalXml

/**
* Query is a fluent interface for constructing a call (GET, POST, DELETE, PUT or
* similar) to a RESTful web service. It is typed so that the representations
Expand Down Expand Up @@ -136,8 +132,8 @@ abstract class Query[
Right(body map( b =>
client.configuration.contentType match {

case "application/json" => UnmarshalJson(b, true).toRepresentation[R](typeR) // TODO: remove rootKey bool
case "text/xml" => UnmarshalXml(b).toRepresentation[R](typeR)
// case "application/json" => null // UnmarshalJson(b, true).toRepresentation[R](typeR) // TODO: remove rootKey bool
// case "text/xml" => null // UnmarshalXml(b).toRepresentation[R](typeR)
case _ => throw new ClientConfigurationException("Narcolepsy can only unmarshal JSON and XML currently, not %s".format(client.configuration.contentType))
}))
}
Expand Down
7 changes: 1 addition & 6 deletions src/main/scala/co/orderly/narcolepsy/Representation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,7 @@ import marshallers.jaxb.JaxbMarshaller
* Scala class that has been marshalled from XML/JSON/whatever by JAXB, Jackson
* or similar.
*/
// TODO: I have added Jaxb and Jackson support back in via extends.
// TODO: In the future this should be decoupled (a Representation
// TODO: should be marshallable by any given Marshaller technology
// TODO: - this can be done by making an implicit conversion
// TODO: available at the correct point.
trait Representation extends JaxbMarshaller with JacksonMarshaller
trait Representation

/**
* ErrorRepresentation is the parent trait for all representations which
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import org.codehaus.jackson.xc._
*/
object RootValueStrategy extends Enumeration {
type RootValueStrategy = Value
val All, NotWrappers, None = RootValueStrategy
val All, NotWrappers, None = Value
}
import RootValueStrategy._

Expand All @@ -50,7 +50,14 @@ case class JacksonUnmarshaller(conf: JacksonConfiguration, json: String) extend
def toRepresentation[R <: Representation](typeR: Class[R]): R = {

val (mapper, ai) = createObjectMapperAndIntrospector(conf)

mapper.getDeserializationConfig().withAnnotationIntrospector(ai)
mapper.getDeserializationConfig().setDateFormat(conf.dateFormat) // TODO: setDateFormat has been deprecated

// Whether or not to add a root key aka "top level segment" when (un)marshalling JSON, as
// per http://stackoverflow.com/questions/5728276/jackson-json-top-level-segment-inclusion
// Unmarshalling only
mapper.configure(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, unwrapRootValue(conf.rootValueStrategy, typeR))

// Return the representation
mapper.readValue(json, typeR).asInstanceOf[R]
Expand All @@ -60,15 +67,17 @@ case class JacksonUnmarshaller(conf: JacksonConfiguration, json: String) extend
/**
* Case class mini-DSL for marshalling via Jackson.
*/
case class JacksonMarshaller(conf: JaxbConfiguration) extends Marshaller with JacksonHelpers {
case class JacksonMarshaller(conf: JacksonConfiguration) extends Marshaller with JacksonHelpers {

/**
* Marshals this representation into JSON via Jackson
*/
def fromRepresentation[R <: Representation](representation: R): String = {

val (mapper, ai) = createObjectMapperAndIntrospector(conf)

mapper.getSerializationConfig().withAnnotationIntrospector(ai)
mapper.getSerializationConfig().setDateFormat(conf.dateFormat) // TODO: setDateFormat has been deprecated

// Return a pretty printed String
val writer = mapper.defaultPrettyPrintingWriter // Deprecated, replace
Expand All @@ -86,17 +95,10 @@ trait JacksonHelpers {
* the supplied configuration. Same for marshalling and
* unmarshalling.
*/
def createObjectMapperAndIntrospector(conf: JacksonConfiguration): (ObjectMapper, AnnotationIntrospector) = {
def createObjectMapperAndIntrospector[R <: Representation](conf: JacksonConfiguration): (ObjectMapper, AnnotationIntrospector) = {

val mapper = new ObjectMapper()

// Whether or not to add a root key aka "top level segment" when (un)marshalling JSON, as
// per http://stackoverflow.com/questions/5728276/jackson-json-top-level-segment-inclusion
mapper.configure(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, unwrapRootValue(conf.rootValueStrategy, typeR))

// The custom date format to use
mapper.getDeserializationConfig().setDateFormat(conf.dateFormat) // TODO: setDateFormat has been deprecated

// How to name the properties (e.g. lower case with underscores)
mapper.setPropertyNamingStrategy(conf.propertyNamingStrategy)

Expand All @@ -113,7 +115,7 @@ trait JacksonHelpers {
/**
* Whether to set unwrap root value to true or false
*/
private def unwrapRootValue[R <: Representation](rvs: RootValueStrategy, typeR: Class[R]): Boolean = rvs match {
def unwrapRootValue[R <: Representation](rvs: RootValueStrategy, typeR: Class[R]): Boolean = rvs match {
case All => true
case None => false
case NotWrappers => isWrapper(typeR)
Expand Down

0 comments on commit b1ef09a

Please sign in to comment.