Play2 Implicit Writes<T> in Java - scala

I have some problem calling my Scala code from Java.
Here is my Scala Class:
case class Foobar(foo: String) extends FoobarParent
object Foobar {
implicit object Format extends Format[Foobar] {
def writes(Foobar: foobar): JsValue = {
....
}
implicit def reads(json: JsValue): JsResult[Foobar] = {
...
}
}
}
Now when I have a method with the following signature:
def publish[T <: FoobarParent](foobarParent: T)(implicit writes: Writes[T]): Unit = {...}
This works fine when calling from Scala code, I simply just do publish[Foobar] (Foobar(...))
However in Java, the signature looks likes this in my IDE:
publish (T FoobarParent, Writes<T> writes)
Now my question is what/how do I fulfil those two parameters in Java?

You usually can get an object's instance like this: Foobar$.MODULE$
and the nested one like this: Foobar.Format$.MODULE$
There's a problem with the companion object here though, because it gets compiled as a different class. It will create a class named Foobar$ which is not of the type Foobar nor does it extends FoobarParent. So you can't just call publish(Foobar$.MODULE$, Foobar.Format$.MODULE$);. I think you'll just have to create a new instance:
publish(new Foobar("..."), Foobar.Format$.MODULE$);

Related

How to implement a minimal mock of a polymorphic method in Scala?

Say I have the following trait and class:
case class Result[A](
header: String,
data: A
)
trait WebClient {
def doSomething[A : TypeTag](name: String): Future[Result[A]]
}
In this example, doSomething is the polymorphic method in question. How can I create a MockWebClient which implements WebClient and have minimal behavior? (The most minimal behavior being doing nothing.) Preferably, I don't want to return a Future.failed because the result shouldn't signify a failure, semantically. Also, I don't want to change the A type of Result[A] to be covariant or contravariant (i.e. +A or -A) because it doesn't make a lot of sense in the context.
Here's my best attempt (which still doesn't compile). It uses a generic class with a generic factory to simulate the return value of the doSomething method. However, I cannot find the correct relationship between A and B:
class MockWebClient[A](val factory: () => Result[A]) extends WebClient {
override def doSomething[B >: A : TypeTag](name: String): Future[Result[B]] = {
Future.successful(factory())
}
}
Also, I have used mockito-scala, but it doesn't work because of type erasure. scalamock also seems interesting, but I would like to know if there is a way to make something similar to my solution work.
If you are sure data field will not be used in the test you could trick the compiler with null.asInstanceOf[A]
val mockWebClient = new WebClient {
override def doSomething[A](name: String): Future[Result[A]] =
Future.successful(Result(name, null.asInstanceOf[A]))
}
If A forms a Monoid you could do it in a type-safe manner with something like
import cats.Monoid
import cats.implicits._
trait WebClient {
def doSomething[A: Monoid](name: String): Future[Result[A]]
}
val mockWebClient = new WebClient {
override def doSomething[A: Monoid](name: String): Future[Result[A]] =
Future.successful(Result(name, implicitly[Monoid[A]].empty))
}
mockWebClient.doSomething[String]("woohoo")

Scala type classes with constructor dependency injection

I'm trying to figure out how to get traditional constructor-based dependency injection to work with type class patterns.
For example, given
trait MyTypeClass[A] {
def doSomething(a: A): Unit
}
class TypeClasses(prefix: String) {
implicit val stringTC = new MyTypeClass[String] {
def doSomething(a: String) = println(s"$prefix a")
}
implicit val intTc = new MyTypeClass[Int] {
def doSomething(a: Int) = println(s"s$prefix $a")
}
}
class MyLogic {
def doSomething[A](a: A)(implicit myTypeClass: MyTypeClass[A]) = myTypeClass.doSomething(a)
doSomething("Hello world")
}
What would be the best way to get the implicit type class instances inside an instance of TypeClasses into MyLogic?
The only things I've come up with are to either
a) Inject an instance of TypeClasses into MyLogic in the constructor, and then import instanceOfTypeClasses._. However this has the downside that it has to be repeated every class, and subclasses can't inherit the import.
or b) make TypeClasses a trait, prefix a def, and have MyLogic extend TypeClasses and then dependency inject an instance for prefix in the constructor. However this becomes messy as it's allowing the dependencies for TypeClasses to bleed into MyLogic.
In case you need dependency injection, as I may assume from your tags, you may try to use distage (slides) DI framework for Scala (disclaimer: I'm the author).
It supports typeclass instance injection.
Because your typeclass instances are created dynamically in the TypeClasses class,
you have to add a TypeClasses constructor parameter in every class that needs
to call a function that requires a typeclass instance.
But, you can remove the import typeclasses._ boilerplate by creating implicit
defs that would extract the instances from the TypeClasses object when it's available as an implicit:
trait MyTypeClass[A] {
def doSomething(a: A): Unit
}
object MyTypeClass {
implicit def intFromTypeClasses(implicit typeClasses: TypeClasses): MyTypeClass[Int] = typeClasses.intTc
implicit def stringFromTypeClasses(implicit typeClasses: TypeClasses): MyTypeClass[String] = typeClasses.stringTC
}
Because the implicit defs are defined in the companion object for MyTypeClass they will always be available without any imports.
Then you should add TypeClasses as an implicit parameter in MyLogic, this would make it available for implicit defs to extract instances from:
class MyLogic(implicit typeClasses: TypeClasses) {
def doSomething[A](a: A)(implicit myTypeClass: MyTypeClass[A]) = myTypeClass.doSomething(a)
doSomething("Hello world")
// same as doSomething("Hello world")(MyTypeClass.stringFromTypeClasses(typeClasses))
}
Then, in distage, declare the following bindings
import distage._
class MyAppModule extends ModuleDef {
make[String].from("myprefix")
make[TypeClasses]
make[MyLogic]
}
And everything is wired:
val ctx: Locator = Injector().produce(new MyAppModule)
implicit val typeClasses = ctx.get[TypeClasses]
ctx.get[MyLogic].doSomething("Hello world")

Spray JSON: How to get implicitly declared objects into read and write methods?

I am currently struggling with spray-json writing a protocol for my data model. For deserialization of JSON data to my data transfer objects, a DAO has to be contacted to check if an appropriate object exists, otherwise a DeserializationException should be thrown.
So far, I have the following:
object MyJsonProtocol extends DefaultJsonProtocol {
implicit object MyDtoJsonFormat extends RootJsonFormat[MyDto] {
override def write(obj: MyDto): JsValue = // Serialization implementation
override def read(json: JsValue): MyDto = {
// parse the JSON, get some parameters, let them be a, b, c
dtoLookup(a, b, c) match {
case Some(dto: MyDto) => dto
case None => throw new DeserializationException("Cannot retrieve object from DAO")
}
}
}
def dtoLookup(a: SomeType, b: SomeOtherType, c: YetAnotherType)(implicit dao: MyDAO): Option[MyDto] = {
// lookup the MyDTO with the dao instance
}
}
My test looks like the following:
class MyJsonProtocolTest extends FlatSpec with Matchers {
implicit val MyDAO = // some test instance, can be a mock object
"The protocol" should "serialize a DTO" in {
val dto: MyDTO = ...
dto.toJson.compactPrint should be("{...}")
}
}
However, the compiler complains that it cannot find the implicit MyDAO when trying to compile the MyJSONProtocol. In When testing Spray services with Scalatest, how to introduce implicit values? I asked yesterday, I was suggested to pass in the implicit parameter directly into the method, but I cannot do this here because the read method is defined in the RootJsonFormat.
When I call the dtoLookup method directly from my test code, it succeeds.
So, how do I get the MyDAO instance into my special JSON format?
One option is to make the implicit parameter a constructor parameter to one of the classes being used. This might require that you turn one of your objects into a class. Then you can make an get method on the companion object of that class that uses an implicit in scope to construct the class with the desired argument.
This doesn't really have to do with spray or scalatest, rather it's just an issue with implicits and implicit scope. Here's a simplified version:
object MyJsonProtocol {
implicit object MyDtoJsonFormat {
def read(x: Int) = dtoLookup
}
def dtoLookup(implicit x: Int) = x + 1
}
And you might consider changing that to:
class MyJsonProtocol(implicit x: Int) {
implicit object MyDtoJsonFormat {
def read(x: Int) = dtoLookup
}
def dtoLookup = x + 1
}
object MyJsonProtol {
def get(implicit x: Int) = new MyJsonProtocol
}
And then you can use this with an implicit in scope:
class MyJsonProtocolTest {
implicit val x = 5
val proto = MyJsonProtol.get
val myReadValue = proto.MyDtoJsonFormat.read //6
}
You can read about the rules for implicit scopes here, especially relevant might be the "Where do Implicits Come From" section.

Scala reflection to instantiate scala.slick.lifted.TableQuery

I have this base trait
trait MyBase {
type M
type T <: Table[M]
val query: TableQuery[T]
}
Where TableQuery is scala.slick.lifted.TableQuery
My subclasses instantiate TableQuery like so:
type M = Account
type T = AccountsTable
val query = TableQuery[T]
I'd like to instantiate the TableQuery in the base trait, possibly by using a lazy val, i.e.
lazy val query: TableQuery[T] = {
...
}
I've been playing around with reflection, but haven't had much luck.
If I understand correctly, what you want is to be able to extend
MyBase by simply defining M and T but without having to explicitly instantiate the TableQuery in each derived class.
Using reflection is not really an option because normally you use TableQuery.apply
for that (as in val query = TableQuery[MyTable]), and this is implemented through a macro,
so you've got a "runtime vs compile-time" issue.
If you absolutely need MyBase to be a trait (as opposed to a class), then I don't see any viable solution.
However if you can turn MyBase into a class and turn M and T into type parameters (instead of abstract types), then there is at least one solution.
As I hinted in another related question (How to define generic type in Scala?), you can
define a type class (say TableQueryBuilder) to capture the call to TableQuery.apply (at the point where the concrete type is known) along with an implicit macro (say TableQueryBuilder.builderForTable) to provide
an instance of this type class. You can then define a method (say TableQueryBuilder.build) to actually instantiate the TableQuery, which will just delegate to job to the type class.
// NOTE: tested with scala 2.11.0 & slick 3.0.0
import scala.reflect.macros.Context
import scala.language.experimental.macros
object TableQueryBuilderMacro {
def createBuilderImpl[T<:AbstractTable[_]:c.WeakTypeTag](c: Context) = {
import c.universe._
val T = weakTypeOf[T]
q"""new TableQueryBuilder[$T]{
def apply(): TableQuery[$T] = {
TableQuery[$T]
}
}"""
}
}
trait TableQueryBuilder[T<:AbstractTable[_]] {
def apply(): TableQuery[T]
}
object TableQueryBuilder {
implicit def builderForTable[T<:AbstractTable[_]]: TableQueryBuilder[T] = macro TableQueryBuilderMacro.createBuilderImpl[T]
def build[T<:AbstractTable[_]:TableQueryBuilder](): TableQuery[T] = implicitly[TableQueryBuilder[T]].apply()
}
The net effect is that you don't need anymore to know the concrete value of the type T in order to be able to instantiate a TableQuery[T],
provided that you have an implicit instance of TableQueryBuilder[T] in scope. In other words, you can shift the need to know the concrete value of T
up to the point where you actually know it.
MyBase (now a class) can then be implemented like this:
class MyBase[M, T <: Table[M] : TableQueryBuilder] {
lazy val query: TableQuery[T] = TableQueryBuilder.build[T]
}
And you can then extend it without the need to explcitly call TableQuery.apply:
class Coffees(tag: Tag) extends Table[(String, Double)](tag, "COFFEES") {
def name = column[String]("COF_NAME")
def price = column[Double]("PRICE")
def * = (name, price)
}
class Derived extends MyBase[(String, Double), Coffees] // That's it!
What happens here is that in Derived's constructor, an implicit value for TableQueryBuilder[Coffees] is implicitly
passed to MyBase's constructor.
The reason why you cannot apply this pattern if MyBase were a trait is pretty mundane: trait constructors cannot have parameters, let alone implicit parameters, so there would be no implicit way
to pass the TableQueryBuilder instance.

Default value for type parameter in Scala

I'm failing to figure out how (if at all) you can set a default value for a type-parameter in Scala.
Currently I have a method similar to this:
def getStage[T <: Stage](key: String): T = {
// Do fancy stuff that returns something
}
But what I'd like to do is provide an implementation of getStage that takes no value for T and uses a default value instead. I tried to just define another method and overload the parameters, but it only leads to one of the methods being completely overriden by the other one. If I have not been clear what I'm trying to do is something like this:
def getStage[T<:Stage = Stage[_]](key: String): T = {
}
I hope it's clear what I'm asking for. Does anyone know how something like this could be achieved?
You can do this kind of thing in a type-safe way using type classes. For example, suppose you've got this type class:
trait Default[A] { def apply(): A }
And the following type hierarchy:
trait Stage
case class FooStage(foo: String) extends Stage
case class BarStage(bar: Int) extends Stage
And some instances:
trait LowPriorityStageInstances {
implicit object barStageDefault extends Default[BarStage] {
def apply() = BarStage(13)
}
}
object Stage extends LowPriorityStageInstances {
implicit object stageDefault extends Default[Stage] {
def apply() = FooStage("foo")
}
}
Then you can write your method like this:
def getStage[T <: Stage: Default](key: String): T =
implicitly[Default[T]].apply()
And it works like this:
scala> getStage("")
res0: Stage = FooStage(foo)
scala> getStage[BarStage]("")
res1: BarStage = BarStage(13)
Which I think is more or less what you want.