From 6958ef53903aabf35b2ba981c0783a68397d1285 Mon Sep 17 00:00:00 2001 From: Arya Irani Date: Wed, 12 Oct 2011 17:50:04 -0400 Subject: [PATCH] Added ScalaCollectionFormParamInjectable{,Provider,ProviderSpec} Split methods between providers into into AbstractScalaCollectionsParamInjectableProvider --- ...laCollectionsParamInjectableProvider.scala | 26 +++++++ .../ScalaCollectionFormParamInjectable.scala | 19 +++++ .../ScalaCollectionQueryParamInjectable.scala | 4 +- ...llectionsFormParamInjectableProvider.scala | 31 ++++++++ ...lectionsQueryParamInjectableProvider.scala | 31 +++----- ...tionsFormParamInjectableProviderSpec.scala | 78 +++++++++++++++++++ ...ionsQueryParamInjectableProviderSpec.scala | 2 +- 7 files changed, 167 insertions(+), 24 deletions(-) create mode 100644 src/main/scala/com/codahale/jersey/inject/AbstractScalaCollectionsParamInjectableProvider.scala create mode 100644 src/main/scala/com/codahale/jersey/inject/ScalaCollectionFormParamInjectable.scala create mode 100644 src/main/scala/com/codahale/jersey/inject/ScalaCollectionsFormParamInjectableProvider.scala create mode 100644 src/test/scala/com/codahale/jersey/inject/specs/ScalaCollectionsFormParamInjectableProviderSpec.scala diff --git a/src/main/scala/com/codahale/jersey/inject/AbstractScalaCollectionsParamInjectableProvider.scala b/src/main/scala/com/codahale/jersey/inject/AbstractScalaCollectionsParamInjectableProvider.scala new file mode 100644 index 0000000..157f8e7 --- /dev/null +++ b/src/main/scala/com/codahale/jersey/inject/AbstractScalaCollectionsParamInjectableProvider.scala @@ -0,0 +1,26 @@ +package com.codahale.jersey.inject + +import com.sun.jersey.core.spi.component.ComponentScope +import com.sun.jersey.server.impl.model.parameter.multivalued.MultivaluedParameterExtractor + +abstract class AbstractScalaCollectionsParamInjectableProvider { + def getScope = ComponentScope.PerRequest + protected def buildExtractor(name: String, default: String, klass: Class[_]): MultivaluedParameterExtractor = { + if (klass == classOf[Seq[String]]) { + new ScalaCollectionStringReaderExtractor[Seq](name, default, Seq) + } else if (klass == classOf[List[String]]) { + new ScalaCollectionStringReaderExtractor[List](name, default, List) + } else if (klass == classOf[Vector[String]]) { + new ScalaCollectionStringReaderExtractor[Vector](name, default, Vector) + } else if (klass == classOf[IndexedSeq[String]]) { + new ScalaCollectionStringReaderExtractor[IndexedSeq](name, default, IndexedSeq) + } else if (klass == classOf[Set[String]]) { + new ScalaCollectionStringReaderExtractor[Set](name, default, Set) + } else if (klass == classOf[Option[String]]) { + new ScalaOptionStringExtractor(name, default) + } else null + } +} + + + diff --git a/src/main/scala/com/codahale/jersey/inject/ScalaCollectionFormParamInjectable.scala b/src/main/scala/com/codahale/jersey/inject/ScalaCollectionFormParamInjectable.scala new file mode 100644 index 0000000..6ef3a45 --- /dev/null +++ b/src/main/scala/com/codahale/jersey/inject/ScalaCollectionFormParamInjectable.scala @@ -0,0 +1,19 @@ +package com.codahale.jersey.inject + +import com.sun.jersey.api.ParamException +import com.sun.jersey.api.core.HttpContext +import com.sun.jersey.server.impl.inject.AbstractHttpContextInjectable +import com.sun.jersey.server.impl.model.parameter.multivalued.{MultivaluedParameterExtractor, ExtractorContainerException} + +class ScalaCollectionFormParamInjectable(extractor: MultivaluedParameterExtractor) + extends AbstractHttpContextInjectable[Object] { + + def getValue(c: HttpContext) = try { + extractor.extract(c.getRequest.getFormParameters) + } catch { + case e: ExtractorContainerException => + throw new ParamException.FormParamException(e.getCause, + extractor.getName, + extractor.getDefaultStringValue) + } +} diff --git a/src/main/scala/com/codahale/jersey/inject/ScalaCollectionQueryParamInjectable.scala b/src/main/scala/com/codahale/jersey/inject/ScalaCollectionQueryParamInjectable.scala index b4afd90..67168c0 100644 --- a/src/main/scala/com/codahale/jersey/inject/ScalaCollectionQueryParamInjectable.scala +++ b/src/main/scala/com/codahale/jersey/inject/ScalaCollectionQueryParamInjectable.scala @@ -6,11 +6,11 @@ import com.sun.jersey.server.impl.inject.AbstractHttpContextInjectable import com.sun.jersey.server.impl.model.parameter.multivalued.{MultivaluedParameterExtractor, ExtractorContainerException} class ScalaCollectionQueryParamInjectable(extractor: MultivaluedParameterExtractor, - decode: Boolean) + decoded: Boolean) extends AbstractHttpContextInjectable[Object] { def getValue(c: HttpContext) = try { - extractor.extract(c.getUriInfo.getQueryParameters(decode)) + extractor.extract(c.getUriInfo.getQueryParameters(decoded)) } catch { case e: ExtractorContainerException => throw new ParamException.QueryParamException(e.getCause, diff --git a/src/main/scala/com/codahale/jersey/inject/ScalaCollectionsFormParamInjectableProvider.scala b/src/main/scala/com/codahale/jersey/inject/ScalaCollectionsFormParamInjectableProvider.scala new file mode 100644 index 0000000..0f871c5 --- /dev/null +++ b/src/main/scala/com/codahale/jersey/inject/ScalaCollectionsFormParamInjectableProvider.scala @@ -0,0 +1,31 @@ +package com.codahale.jersey.inject + +import javax.ws.rs.ext.Provider +import com.sun.jersey.api.model.Parameter +import com.sun.jersey.core.spi.component.{ComponentScope, ComponentContext} +import com.sun.jersey.spi.inject.{Injectable, InjectableProvider} +import com.sun.jersey.server.impl.model.parameter.multivalued.MultivaluedParameterExtractor +import javax.ws.rs.{FormParam, QueryParam} + +@Provider +class ScalaCollectionsFormParamInjectableProvider + extends AbstractScalaCollectionsParamInjectableProvider + with InjectableProvider[FormParam, Parameter] +{ + def getInjectable(ic: ComponentContext, a: FormParam, c: Parameter): Injectable[_] = { + val parameterName = c.getSourceName() + if (parameterName != null && !parameterName.isEmpty) { + buildInjectable(parameterName, c.getDefaultValue, c.getParameterClass) + } else null + } + + private def buildInjectable(name: String, default: String, klass: Class[_]): Injectable[_ <: Object] = { + val extractor = buildExtractor(name, default, klass) + if (extractor != null) { + new ScalaCollectionFormParamInjectable(extractor) + } else null + } +} + + + diff --git a/src/main/scala/com/codahale/jersey/inject/ScalaCollectionsQueryParamInjectableProvider.scala b/src/main/scala/com/codahale/jersey/inject/ScalaCollectionsQueryParamInjectableProvider.scala index 47c706c..03e6938 100644 --- a/src/main/scala/com/codahale/jersey/inject/ScalaCollectionsQueryParamInjectableProvider.scala +++ b/src/main/scala/com/codahale/jersey/inject/ScalaCollectionsQueryParamInjectableProvider.scala @@ -1,15 +1,17 @@ package com.codahale.jersey.inject -import javax.ws.rs.QueryParam import javax.ws.rs.ext.Provider import com.sun.jersey.api.model.Parameter import com.sun.jersey.core.spi.component.{ComponentScope, ComponentContext} import com.sun.jersey.spi.inject.{Injectable, InjectableProvider} import com.sun.jersey.server.impl.model.parameter.multivalued.MultivaluedParameterExtractor +import javax.ws.rs.{FormParam, QueryParam} @Provider -class ScalaCollectionsQueryParamInjectableProvider extends InjectableProvider[QueryParam, Parameter] { - def getScope = ComponentScope.PerRequest +class ScalaCollectionsQueryParamInjectableProvider + extends AbstractScalaCollectionsParamInjectableProvider + with InjectableProvider[QueryParam, Parameter] +{ def getInjectable(ic: ComponentContext, a: QueryParam, c: Parameter): Injectable[_] = { val parameterName = c.getSourceName() if (parameterName != null && !parameterName.isEmpty) { @@ -17,26 +19,13 @@ class ScalaCollectionsQueryParamInjectableProvider extends InjectableProvider[Qu } else null } - private def buildExtractor(name: String, default: String, klass: Class[_]): MultivaluedParameterExtractor = { - if (klass == classOf[Seq[String]]) { - new ScalaCollectionStringReaderExtractor[Seq](name, default, Seq) - } else if (klass == classOf[List[String]]) { - new ScalaCollectionStringReaderExtractor[List](name, default, List) - } else if (klass == classOf[Vector[String]]) { - new ScalaCollectionStringReaderExtractor[Vector](name, default, Vector) - } else if (klass == classOf[IndexedSeq[String]]) { - new ScalaCollectionStringReaderExtractor[IndexedSeq](name, default, IndexedSeq) - } else if (klass == classOf[Set[String]]) { - new ScalaCollectionStringReaderExtractor[Set](name, default, Set) - } else if (klass == classOf[Option[String]]) { - new ScalaOptionStringExtractor(name, default) - } else null - } - - private def buildInjectable(name: String, default: String, decode: Boolean, klass: Class[_]): Injectable[_ <: Object] = { + private def buildInjectable(name: String, default: String, decoded: Boolean, klass: Class[_]): Injectable[_ <: Object] = { val extractor = buildExtractor(name, default, klass) if (extractor != null) { - new ScalaCollectionQueryParamInjectable(extractor, decode) + new ScalaCollectionQueryParamInjectable(extractor, decoded) } else null } } + + + diff --git a/src/test/scala/com/codahale/jersey/inject/specs/ScalaCollectionsFormParamInjectableProviderSpec.scala b/src/test/scala/com/codahale/jersey/inject/specs/ScalaCollectionsFormParamInjectableProviderSpec.scala new file mode 100644 index 0000000..73cd8c1 --- /dev/null +++ b/src/test/scala/com/codahale/jersey/inject/specs/ScalaCollectionsFormParamInjectableProviderSpec.scala @@ -0,0 +1,78 @@ +package com.codahale.jersey.inject.specs + +import com.codahale.simplespec.Spec +import org.junit.Test +import com.sun.jersey.api.model.Parameter +import com.sun.jersey.core.spi.component.{ComponentContext, ComponentScope} +import com.sun.jersey.core.util.MultivaluedMapImpl +import javax.ws.rs.FormParam +import com.codahale.jersey.inject.{ScalaCollectionsFormParamInjectableProvider, ScalaCollectionFormParamInjectable} +import com.sun.jersey.api.core.{HttpRequestContext, HttpContext} +import com.sun.jersey.api.representation.Form + +class ScalaCollectionsFormParamInjectableProviderSpec extends Spec { + class `A Scala collections form param injectable provider` { + val httpContext = mock[HttpContext] + val requestContext = mock[HttpRequestContext] + + val params = new Form() + params.add("name", "one") + params.add("name", "two") + params.add("name", "three") + + httpContext.getRequest returns requestContext + requestContext.getFormParameters returns params + + val context = mock[ComponentContext] + val formParam = mock[FormParam] + + val provider = new ScalaCollectionsFormParamInjectableProvider + + + @Test def `has a per-request scope` = { + provider.getScope.must(be(ComponentScope.PerRequest)) + } + + @Test def `returns an injectable for Seq instances` = { + val param = new Parameter(Array(), null, null, "name", null, classOf[Seq[String]], false, "default") + val injectable = provider.getInjectable(context, formParam, param).asInstanceOf[ScalaCollectionFormParamInjectable] + + injectable.getValue(httpContext).must(be(Seq("one", "two", "three"))) + } + + @Test def `returns an injectable for List instances` = { + val param = new Parameter(Array(), null, null, "name", null, classOf[List[String]], false, "default") + val injectable = provider.getInjectable(context, formParam, param).asInstanceOf[ScalaCollectionFormParamInjectable] + + injectable.getValue(httpContext).must(be(List("one", "two", "three"))) + } + + @Test def `returns an injectable for Vector instances` = { + val param = new Parameter(Array(), null, null, "name", null, classOf[Vector[String]], false, "default") + val injectable = provider.getInjectable(context, formParam, param).asInstanceOf[ScalaCollectionFormParamInjectable] + + injectable.getValue(httpContext).must(be(Vector("one", "two", "three"))) + } + + @Test def `returns an injectable for IndexedSeq instances` = { + val param = new Parameter(Array(), null, null, "name", null, classOf[IndexedSeq[String]], false, "default") + val injectable = provider.getInjectable(context, formParam, param).asInstanceOf[ScalaCollectionFormParamInjectable] + + injectable.getValue(httpContext).must(be(IndexedSeq("one", "two", "three"))) + } + + @Test def `return an injectable for Set instances` = { + val param = new Parameter(Array(), null, null, "name", null, classOf[Set[String]], false, "default") + val injectable = provider.getInjectable(context, formParam, param).asInstanceOf[ScalaCollectionFormParamInjectable] + + injectable.getValue(httpContext).must(be(Set("one", "two", "three"))) + } + + @Test def `returns an injectable for Option instances` = { + val param = new Parameter(Array(), null, null, "name", null, classOf[Option[String]], false, "default") + val injectable = provider.getInjectable(context, formParam, param).asInstanceOf[ScalaCollectionFormParamInjectable] + + injectable.getValue(httpContext).must(be(Some("one"))) + } + } +} diff --git a/src/test/scala/com/codahale/jersey/inject/specs/ScalaCollectionsQueryParamInjectableProviderSpec.scala b/src/test/scala/com/codahale/jersey/inject/specs/ScalaCollectionsQueryParamInjectableProviderSpec.scala index 399dc96..152747b 100644 --- a/src/test/scala/com/codahale/jersey/inject/specs/ScalaCollectionsQueryParamInjectableProviderSpec.scala +++ b/src/test/scala/com/codahale/jersey/inject/specs/ScalaCollectionsQueryParamInjectableProviderSpec.scala @@ -5,9 +5,9 @@ import org.junit.Test import javax.ws.rs.QueryParam import com.sun.jersey.api.model.Parameter import com.sun.jersey.core.spi.component.{ComponentContext, ComponentScope} -import com.codahale.jersey.inject.{ScalaCollectionQueryParamInjectable, ScalaCollectionsQueryParamInjectableProvider} import com.sun.jersey.core.util.MultivaluedMapImpl import com.sun.jersey.api.core.{HttpContext, ExtendedUriInfo} +import com.codahale.jersey.inject.{ScalaCollectionsQueryParamInjectableProvider, ScalaCollectionQueryParamInjectable} class ScalaCollectionsQueryParamInjectableProviderSpec extends Spec { class `A Scala collections query param injectable provider` {