scalaplayframeworkplay-authenticate

Play 2.5 How to convert from Scala Form to Java Form?


This is a bit of an odd situation because with the Play framework one stick to either Java or Scala. In my case, I want Scala but also want to build of top of the play-authenticate project that is implemented as a Play Java plugin (and not Scala).

Attempting to migrate their usage sample to Scala and after doing most of the migration to Scala I bumped into the issue of having Scala play.api.data.Form types and need to pass to the play-authenticate framework Java's play.data.Form type. Therefore I need conversion between these two separate (no common abstraction or anything) classes.

I already checked the play.core.j.JavaHelpers implementation but there is nothing to convert between the two separate Form types. I could do it manually but it is a maintenance toll and was wondering if anyone has already bumped into this and how it was solved?

UPDATE I tried PlayMagicForJava as follows but there was no magic :X

import javax.inject.{Inject, Singleton}

import play.api.data.Forms._
import play.api.i18n.Messages
import play.api.mvc.RequestHeader

case class Signup(email: String, password: String, repeatPassword: String, username: String)

@Singleton
class SignupForm @Inject() (implicit val request: RequestHeader, messages: Messages) {
  import play.core.j.PlayMagicForJava._

  val Instance : play.data.Form[Signup] = play.api.data.Form {
    mapping(
      "email" -> email,
      "password" -> nonEmptyText(minLength = 5),
      "repeatPassword" -> nonEmptyText(minLength = 5),
      "username" -> nonEmptyText()
    )(Signup.apply)(Signup.unapply).
      verifying(messages("playauthenticate.password.signup.error.passwords_not_same"),
        data => data.password != null && !data.password.isEmpty && data.password.equals(data.repeatPassword))
  }
}

and the error:

[error] SignupForm.scala:16: type mismatch;
[error]  found   : play.api.data.Form[views.form.Signup]
[error]  required: play.data.Form[views.form.Signup]
[error]       val Instance : play.data.Form[Signup] = Form {

Solution

  • Very unfortunately the only way was to rewrite the affected Forms to Play Java Forms. The hybrid approach leads to issues in the views that expect Scala play.api.data.Form types and not Java play.data.Form types but the solution to support this hybrid approach was to import PlayMagicForJava static context into the affected views.