diff --git a/src/main/scala/com/codahale/jersey/providers/JValueProvider.scala b/src/main/scala/com/codahale/jersey/providers/JValueProvider.scala deleted file mode 100644 index bd25c8a..0000000 --- a/src/main/scala/com/codahale/jersey/providers/JValueProvider.scala +++ /dev/null @@ -1,72 +0,0 @@ -package com.codahale.jersey.providers - -import java.lang.annotation.Annotation -import java.lang.reflect.Type -import javax.ws.rs.{WebApplicationException, Consumes} -import javax.ws.rs.core.{Response, MultivaluedMap, MediaType} -import javax.ws.rs.core.Response.Status -import javax.ws.rs.ext.Provider -import com.sun.jersey.core.provider.AbstractMessageReaderWriterProvider -import com.codahale.jerkson.AST.JValue -import com.codahale.jerkson.{Json, ParsingException} -import org.slf4j.LoggerFactory -import java.io.{IOException, InputStream, OutputStream} - -@Provider -@Consumes(Array(MediaType.APPLICATION_JSON)) -class JValueProvider extends AbstractMessageReaderWriterProvider[JValue] { - private val logger = LoggerFactory.getLogger(classOf[JValueProvider]) - - def writeTo(json: JValue, - t: Class[_], - genericType: Type, - annotations: Array[Annotation], - mediaType: MediaType, - httpHeaders: MultivaluedMap[String, AnyRef], - entityStream: OutputStream) { - try { - Json.generate(json, entityStream) - } catch { - case e: IOException => logger.debug("Error writing to stream", e) - case e => logger.error("Error encoding %s as JSON".format(json), e) - } - } - - def isWriteable(t: Class[_], - genericType: Type, - annotations: Array[Annotation], - mediaType: MediaType) = - MediaType.APPLICATION_JSON_TYPE.isCompatible(mediaType) && - classOf[JValue].isAssignableFrom(t) - - def readFrom(t: Class[JValue], - genericType: Type, - annotations: Array[Annotation], - mediaType: MediaType, - httpHeaders: MultivaluedMap[String, String], - entityStream: InputStream): JValue = { - try { - Json.parse[JValue](entityStream) - } catch { - case e: ParsingException => { - throw new WebApplicationException(Response.status(Status.BAD_REQUEST) - .entity(e.getMessage) - .build) - } - case e => { - e match { - case _: IOException => logger.debug("Error writing to stream", e) - case _ => logger.error("Error decoding JSON request entity", e) - } - throw e - } - } - } - - def isReadable(t: Class[_], - genericType: Type, - annotations: Array[Annotation], - mediaType: MediaType) = - MediaType.APPLICATION_JSON_TYPE.isCompatible(mediaType) && - classOf[JValue].isAssignableFrom(t) -} diff --git a/src/main/scala/com/codahale/jersey/providers/ArrayProvider.scala b/src/main/scala/com/codahale/jersey/providers/JerksonProvider.scala similarity index 82% rename from src/main/scala/com/codahale/jersey/providers/ArrayProvider.scala rename to src/main/scala/com/codahale/jersey/providers/JerksonProvider.scala index abcc0e8..25d5ae2 100644 --- a/src/main/scala/com/codahale/jersey/providers/ArrayProvider.scala +++ b/src/main/scala/com/codahale/jersey/providers/JerksonProvider.scala @@ -15,10 +15,10 @@ import scala.reflect.Manifest @Provider @Produces(Array(MediaType.APPLICATION_JSON)) @Consumes(Array(MediaType.APPLICATION_JSON)) -class ArrayProvider[A] extends AbstractMessageReaderWriterProvider[Array[A]] { - private val logger = LoggerFactory.getLogger(classOf[ArrayProvider[A]]) +class JerksonProvider[A] extends AbstractMessageReaderWriterProvider[A] { + private val logger = LoggerFactory.getLogger(classOf[JerksonProvider[_]]) - def readFrom(klass: Class[Array[A]], + def readFrom(klass: Class[A], genericType: Type, annotations: Array[Annotation], mediaType: MediaType, @@ -38,9 +38,9 @@ class ArrayProvider[A] extends AbstractMessageReaderWriterProvider[Array[A]] { def isReadable(klass: Class[_], genericType: Type, annotations: Array[Annotation], - mediaType: MediaType) = klass.isArray + mediaType: MediaType) = mediaType.isCompatible(MediaType.APPLICATION_JSON_TYPE) - def writeTo(t: Array[A], + def writeTo(t: A, klass: Class[_], genericType: Type, annotations: Array[Annotation], @@ -51,12 +51,12 @@ class ArrayProvider[A] extends AbstractMessageReaderWriterProvider[Array[A]] { Json.generate(t, entityStream) } catch { case e: IOException => logger.debug("Error writing to stream", e) - case e => logger.error("Error encoding %s as JSON".format(t.mkString("Array(", ",", ")")), e) + case e => logger.error("Error encoding %s as JSON".format(t, e)) } } def isWriteable(klass: Class[_], genericType: Type, annotations: Array[Annotation], - mediaType: MediaType) = klass.isArray + mediaType: MediaType) = mediaType.isCompatible(MediaType.APPLICATION_JSON_TYPE) } diff --git a/src/main/scala/com/codahale/jersey/providers/JsonCaseClassProvider.scala b/src/main/scala/com/codahale/jersey/providers/JsonCaseClassProvider.scala deleted file mode 100644 index 72303e9..0000000 --- a/src/main/scala/com/codahale/jersey/providers/JsonCaseClassProvider.scala +++ /dev/null @@ -1,73 +0,0 @@ -package com.codahale.jersey.providers - -import scala.reflect.Manifest -import java.lang.annotation.Annotation -import java.lang.reflect.Type -import javax.ws.rs.{WebApplicationException, Produces, Consumes} -import javax.ws.rs.core.Response.Status -import javax.ws.rs.core.{Response, MultivaluedMap, MediaType} -import com.sun.jersey.core.provider.AbstractMessageReaderWriterProvider -import javax.ws.rs.ext.Provider -import com.codahale.jerkson.{ParsingException, Json} -import org.slf4j.LoggerFactory -import java.io.{IOException, InputStream, OutputStream} - -@Provider -@Produces(Array(MediaType.APPLICATION_JSON)) -@Consumes(Array(MediaType.APPLICATION_JSON)) -class JsonCaseClassProvider extends AbstractMessageReaderWriterProvider[Product] { - private val logger = LoggerFactory.getLogger(classOf[JsonCaseClassProvider]) - - def writeTo(json: Product, - t: Class[_], - genericType: Type, - annotations: Array[Annotation], - mediaType: MediaType, - httpHeaders: MultivaluedMap[String, AnyRef], - entityStream: OutputStream) { - try { - Json.generate(json, entityStream) - } catch { - case e: IOException => logger.debug("Error writing to stream", e) - case e => logger.error("Error encoding %s as JSON".format(json), e) - } - } - - def isWriteable(t: Class[_], - genericType: Type, - annotations: Array[Annotation], - mediaType: MediaType) = - MediaType.APPLICATION_JSON_TYPE.isCompatible(mediaType) && - classOf[Product].isAssignableFrom(t) - - def readFrom(t: Class[Product], - genericType: Type, - annotations: Array[Annotation], - mediaType: MediaType, - httpHeaders: MultivaluedMap[String, String], - entityStream: InputStream): Product = { - try { - Json.parse(entityStream)(Manifest.classType(t)) - } catch { - case e: ParsingException => { - throw new WebApplicationException(Response.status(Status.BAD_REQUEST) - .entity(e.getMessage) - .build) - } - case e => { - e match { - case e: IOException => logger.debug("Error reading from stream", e) - case _ => logger.error("Error decoding JSON request entity", e) - } - throw e - } - } - } - - def isReadable(t: Class[_], - genericType: Type, - annotations: Array[Annotation], - mediaType: MediaType): Boolean = - MediaType.APPLICATION_JSON_TYPE.isCompatible(mediaType) && - classOf[Product].isAssignableFrom(t) -} diff --git a/src/test/scala/com/codahale/jersey/providers/specs/JValueProviderSpec.scala b/src/test/scala/com/codahale/jersey/providers/specs/JValueProviderSpec.scala deleted file mode 100644 index d73931c..0000000 --- a/src/test/scala/com/codahale/jersey/providers/specs/JValueProviderSpec.scala +++ /dev/null @@ -1,63 +0,0 @@ -package com.codahale.jersey.providers.specs - -import com.codahale.simplespec.Spec -import com.codahale.jersey.providers.JValueProvider -import javax.ws.rs.core.MediaType -import com.codahale.jerkson.AST._ -import javax.ws.rs.WebApplicationException -import java.io.{ByteArrayOutputStream, ByteArrayInputStream} -import org.junit.Test - -class JValueProviderSpec extends Spec { - class `A JValue instance` { - val value = mock[JValue] - val provider = new JValueProvider - - @Test def `is writable` = { - provider.isWriteable(value.getClass, null, null, MediaType.APPLICATION_JSON_TYPE).must(be(true)) - } - - @Test def `is readable` = { - provider.isReadable(value.getClass, null, null, MediaType.APPLICATION_JSON_TYPE).must(be(true)) - } - } - - class `Parsing an application/json request entity` { - val entity = "{\"yay\": 1}" - val provider = new JValueProvider - - @Test def `returns a JValue instance` = { - val value = provider.readFrom(null, null, null, null, null, new ByteArrayInputStream(entity.getBytes)) - - value.must(be(JObject(List(JField("yay", JInt(1)))))) - } - } - - class `Parsing an invalid application/json request entity` { - val entity = "{\"yay\": 1" - val provider = new JValueProvider - - @Test def `throws a 400 Bad Request WebApplicationException` = { - evaluating { - provider.readFrom(null, null, null, null, null, new ByteArrayInputStream(entity.getBytes)) - }.must(throwAnExceptionLike { - case e: WebApplicationException => { - val response = e.getResponse - response.getStatus.must(be(400)) - response.getEntity.must(be("Malformed JSON. Unexpected end-of-input: expected close marker for OBJECT at character offset 26.")) - } - }) - } - } - - class `Rendering an application/json response entity` { - val provider = new JValueProvider - val json = JObject(List(JField("yay", JInt(1)))) - - @Test def `produces a compact JSON object` = { - val output = new ByteArrayOutputStream - provider.writeTo(json, null, null, null, MediaType.APPLICATION_JSON_TYPE, null, output) - output.toString.must(be("{\"yay\":1}")) - } - } -} diff --git a/src/test/scala/com/codahale/jersey/providers/specs/ArrayProviderSpec.scala b/src/test/scala/com/codahale/jersey/providers/specs/JerksonProviderSpec.scala similarity index 92% rename from src/test/scala/com/codahale/jersey/providers/specs/ArrayProviderSpec.scala rename to src/test/scala/com/codahale/jersey/providers/specs/JerksonProviderSpec.scala index 7af16d3..92d53f8 100644 --- a/src/test/scala/com/codahale/jersey/providers/specs/ArrayProviderSpec.scala +++ b/src/test/scala/com/codahale/jersey/providers/specs/JerksonProviderSpec.scala @@ -3,12 +3,12 @@ package com.codahale.jersey.providers.specs import com.codahale.simplespec.Spec import org.junit.Test import javax.ws.rs.core.MediaType -import com.codahale.jersey.providers.ArrayProvider +import com.codahale.jersey.providers.JerksonProvider import javax.ws.rs.WebApplicationException import java.io.{ByteArrayOutputStream, ByteArrayInputStream} -class ArrayProviderSpec extends Spec { - private val provider = new ArrayProvider[Int] +class JerksonProviderSpec extends Spec { + private val provider = new JerksonProvider[Array[Int]] class `An array of ints` { @Test def `is writable` = { diff --git a/src/test/scala/com/codahale/jersey/providers/specs/JsonCaseClassProviderSpec.scala b/src/test/scala/com/codahale/jersey/providers/specs/JsonCaseClassProviderSpec.scala deleted file mode 100644 index 7e13690..0000000 --- a/src/test/scala/com/codahale/jersey/providers/specs/JsonCaseClassProviderSpec.scala +++ /dev/null @@ -1,78 +0,0 @@ -package com.codahale.jersey.providers.specs - -import com.codahale.simplespec.Spec -import javax.ws.rs.core.MediaType -import com.codahale.jersey.providers.JsonCaseClassProvider -import java.io.{ByteArrayInputStream, ByteArrayOutputStream} -import javax.ws.rs.WebApplicationException -import org.junit.Test - -case class Role(name: String) -case class Person(name: String, age: Int, roles: List[Role]) - -class JsonCaseClassProviderSpec extends Spec { - val provider = new JsonCaseClassProvider - val entity = """{"name":"Coda","age":29,"roles":[{"name":"badass"},{"name":"beardo"}]}""" - val coda = Person("Coda", 29, List(Role("badass"), Role("beardo"))) - - class `A case class instance` { - @Test def `is writable` = { - provider.isWriteable(coda.getClass, null, null, MediaType.APPLICATION_JSON_TYPE).must(be(true)) - } - - @Test def `is readable` = { - provider.isReadable(coda.getClass, null, null, MediaType.APPLICATION_JSON_TYPE).must(be(true)) - } - } - - class `Parsing an application/json request entity` { - @Test def `returns a case class instance` = { - val value = provider.readFrom(classOf[Person].asInstanceOf[Class[Product]], null, null, null, null, new ByteArrayInputStream(entity.getBytes)) - - value.must(be(coda)) - } - } - - class `Parsing an malformed application/json request entity` { - val entity = "{\"yay\": 1" - val provider = new JsonCaseClassProvider - - @Test def `throws a 400 Bad Request WebApplicationException` = { - evaluating { - provider.readFrom(classOf[Role].asInstanceOf[Class[Product]], null, null, null, null, new ByteArrayInputStream(entity.getBytes)) - }.must(throwAnExceptionLike { - case e: WebApplicationException => { - val response = e.getResponse - response.getStatus.must(be(400)) - response.getEntity.must(be("Malformed JSON. Unexpected end-of-input: expected close marker for OBJECT at character offset 26.")) - } - }) - } - } - - class `Parsing an invalid application/json request entity` { - val entity = "{\"yay\": 1}" - val provider = new JsonCaseClassProvider - - @Test def `throws a 400 Bad Request WebApplicationException` = { - evaluating { - provider.readFrom(classOf[Role].asInstanceOf[Class[Product]], null, null, null, null, new ByteArrayInputStream(entity.getBytes)) - }.must(throwAnExceptionLike { - case e: WebApplicationException => { - val response = e.getResponse - response.getStatus.must(be(400)) - response.getEntity.must(be("Invalid JSON. Needed [name], but found [yay].")) - } - }) - } - } - - class `Rendering an application/json response entity` { - @Test def `produces a compact JSON object` = { - val output = new ByteArrayOutputStream - provider.writeTo(coda, null, null, null, MediaType.APPLICATION_JSON_TYPE, null, output) - - output.toString.must(be(entity)) - } - } -}