From 3ac9d7b77cda20578d8c77f8dc3d88d64931b98e Mon Sep 17 00:00:00 2001 From: ryan Date: Sat, 9 Nov 2019 16:44:45 +0800 Subject: [PATCH 1/2] Adding basic-java sample, a Java-based play application with default JAVA twirl import (making JAVA forms work in the Twirl template). Update user guide. --- src/docs/asciidoc/34-compiler-options.adoc | 9 ++++ .../groovy/app/controllers/Application.java | 31 +++++++++++ .../basic-java/groovy/app/model/User.java | 8 +++ .../groovy/app/views/indexUserForm.scala.html | 27 ++++++++++ .../groovy/app/views/main.scala.html | 15 ++++++ .../basic-java/groovy/basic-java.sample.conf | 2 + .../samples/basic-java/groovy/build.gradle | 48 ++++++++++++++++++ .../basic-java/groovy/conf/application.conf | 44 ++++++++++++++++ .../samples/basic-java/groovy/conf/routes | 9 ++++ .../groovy/public/images/favicon.png | Bin 0 -> 687 bytes .../groovy/public/javascripts/hello.js | 3 ++ .../groovy/public/stylesheets/main.css | 0 .../samples/basic-java/groovy/settings.gradle | 1 + .../groovy/test/ApplicationSpec.scala | 47 +++++++++++++++++ .../groovy/test/IntegrationSpec.scala | 22 ++++++++ .../groovy/app/controllers/Application.scala | 2 +- 16 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 src/docs/samples/basic-java/groovy/app/controllers/Application.java create mode 100644 src/docs/samples/basic-java/groovy/app/model/User.java create mode 100644 src/docs/samples/basic-java/groovy/app/views/indexUserForm.scala.html create mode 100644 src/docs/samples/basic-java/groovy/app/views/main.scala.html create mode 100644 src/docs/samples/basic-java/groovy/basic-java.sample.conf create mode 100644 src/docs/samples/basic-java/groovy/build.gradle create mode 100644 src/docs/samples/basic-java/groovy/conf/application.conf create mode 100644 src/docs/samples/basic-java/groovy/conf/routes create mode 100644 src/docs/samples/basic-java/groovy/public/images/favicon.png create mode 100644 src/docs/samples/basic-java/groovy/public/javascripts/hello.js create mode 100644 src/docs/samples/basic-java/groovy/public/stylesheets/main.css create mode 100644 src/docs/samples/basic-java/groovy/settings.gradle create mode 100644 src/docs/samples/basic-java/groovy/test/ApplicationSpec.scala create mode 100644 src/docs/samples/basic-java/groovy/test/IntegrationSpec.scala diff --git a/src/docs/asciidoc/34-compiler-options.adoc b/src/docs/asciidoc/34-compiler-options.adoc index b700ec93..23665717 100644 --- a/src/docs/asciidoc/34-compiler-options.adoc +++ b/src/docs/asciidoc/34-compiler-options.adoc @@ -6,4 +6,13 @@ If your Play application requires additional Scala compiler flags, you can add t .build.gradle ---- include::{samplesCodeDir}/configure-compiler/groovy/build.gradle[tag=additional-params] +---- + +When working with Twirl templates in Java-based project, the Java default imports needs to be enabled to include necessary +conversions of Scala objects to Java objects, e.g. Scala forms to Java forms. + +[source,groovy] +.build.gradle +---- +include::{samplesCodeDir}/basic-java/groovy/build.gradle[tag=enable-java-default-imports-in-templates] ---- \ No newline at end of file diff --git a/src/docs/samples/basic-java/groovy/app/controllers/Application.java b/src/docs/samples/basic-java/groovy/app/controllers/Application.java new file mode 100644 index 00000000..2c687082 --- /dev/null +++ b/src/docs/samples/basic-java/groovy/app/controllers/Application.java @@ -0,0 +1,31 @@ +package controllers; + +import play.mvc.Controller; +import play.mvc.Result; +import org.apache.commons.lang3.StringUtils; +import play.data.Form; +import play.data.FormFactory; +import javax.inject.*; +import model.*; + +@Singleton +public class Application extends Controller { + + private FormFactory ff; + + @Inject + public Application(FormFactory ff) { + this.ff = ff; + } + + public Result index() { + + Form userForm = ff.form(User.class).bindFromRequest(); + + return ok(views.html.indexUserForm.render( + StringUtils.trim(" Your new application is ready. "), + userForm + )); + } + +} diff --git a/src/docs/samples/basic-java/groovy/app/model/User.java b/src/docs/samples/basic-java/groovy/app/model/User.java new file mode 100644 index 00000000..91ea35db --- /dev/null +++ b/src/docs/samples/basic-java/groovy/app/model/User.java @@ -0,0 +1,8 @@ +package model; + +public class User { + + public String username; + public String mobile; + +} \ No newline at end of file diff --git a/src/docs/samples/basic-java/groovy/app/views/indexUserForm.scala.html b/src/docs/samples/basic-java/groovy/app/views/indexUserForm.scala.html new file mode 100644 index 00000000..168cbdc3 --- /dev/null +++ b/src/docs/samples/basic-java/groovy/app/views/indexUserForm.scala.html @@ -0,0 +1,27 @@ +@(message: String, userForm : play.data.Form[model.User]) + +@main("Welcome to Play") { + +

@message

+ +

User Form

+ +@helper.form(action = routes.Application.index, 'id -> "userFormId") { + +
+ @helper.inputText( + field = userForm("username"), + args = '_label -> "Username", 'id -> "username" + ) +
+ +
+ @helper.inputText( + field = userForm("mobile"), + args = '_label -> "Mobile", 'id -> "mobile" + ) +
+ +} + +} diff --git a/src/docs/samples/basic-java/groovy/app/views/main.scala.html b/src/docs/samples/basic-java/groovy/app/views/main.scala.html new file mode 100644 index 00000000..5025aa5b --- /dev/null +++ b/src/docs/samples/basic-java/groovy/app/views/main.scala.html @@ -0,0 +1,15 @@ +@(title: String)(content: Html) + + + + + + @title + + + + + + @content + + diff --git a/src/docs/samples/basic-java/groovy/basic-java.sample.conf b/src/docs/samples/basic-java/groovy/basic-java.sample.conf new file mode 100644 index 00000000..3aaf111d --- /dev/null +++ b/src/docs/samples/basic-java/groovy/basic-java.sample.conf @@ -0,0 +1,2 @@ +executable: gradle +args: tasks diff --git a/src/docs/samples/basic-java/groovy/build.gradle b/src/docs/samples/basic-java/groovy/build.gradle new file mode 100644 index 00000000..68d962eb --- /dev/null +++ b/src/docs/samples/basic-java/groovy/build.gradle @@ -0,0 +1,48 @@ +// tag::use-plugin[] +plugins { + id 'org.gradle.playframework' version '0.9' +} + +repositories { + jcenter() + maven { + name "lightbend-maven-release" + url "https://repo.lightbend.com/lightbend/maven-releases" + } + ivy { + name "lightbend-ivy-release" + url "https://repo.lightbend.com/lightbend/ivy-releases" + layout "ivy" + } +} +// end::use-plugin[] + +play { + injectedRoutesGenerator = true +} + +dependencies { + implementation 'commons-lang:commons-lang:2.6' + testImplementation "com.google.guava:guava:17.0" + testImplementation "org.scalatestplus.play:scalatestplus-play_2.12:3.1.2" + implementation "com.typesafe.play:play-guice_2.12:2.6.15" + implementation "ch.qos.logback:logback-classic:1.2.3" + + implementation group: 'com.typesafe.play', name: 'play-java-forms_2.12', version: '2.6.15' +} + +// tag::enable-java-default-imports-in-templates[] +sourceSets { + main { + twirl { + defaultImports = org.gradle.playframework.sourcesets.TwirlImports.JAVA + } + } +} + +// alternatively +// compilePlayTwirlTemplates { +// defaultImports = org.gradle.playframework.sourcesets.TwirlImports.JAVA +// } + +// end::enable-java-default-imports-in-templates[] diff --git a/src/docs/samples/basic-java/groovy/conf/application.conf b/src/docs/samples/basic-java/groovy/conf/application.conf new file mode 100644 index 00000000..44d32000 --- /dev/null +++ b/src/docs/samples/basic-java/groovy/conf/application.conf @@ -0,0 +1,44 @@ +# This is the main configuration file for the application. +# ~~~~~ + +# Secret key +# ~~~~~ +# The secret key is used to secure cryptographics functions. +# +# This must be changed for production, but we recommend not changing it in this file. +# +# See http://www.playframework.com/documentation/latest/ApplicationSecret for more details. +play.http.secret.key="dxbAjiDdqlIV83LY<:;hSxql?tG`CPNgXEXt2asjk>lYQezT{T_ZJ?}AL z5NC{NW(ESID=>(O3&Eg8 zmA9J&6c`h4_f6L;=bU>_H8aNG`kfvCj9zomNt)?O;rzWqZs0LEt%1WB218%1fo9uB zsW^yhBR7C(mqN%GEK9&msg0~ zWY?#bf4q8G-~2KttQZ($odJvy&_-~f?9*ThK@fwR$U^1)p*8=_+^3BXx0$i1BC8XC zr21u6D5nVK&^!dOAw&|1E;qC3uFNj3*Jj#&%Oje@0D-nhfmM*o%^5f}-pxQ07(95H z3|LoV>V19w#rLgmRmtVy9!T3M3FUE3><0T8&b3yEsWcLW`0(=1+qsqc(k(ymBLK0h zK!6(6$7MX~M`-QA2$wk7n(7hhkJ}4Rwi-Vd(_ZFX1Yk7TXuB0IJYpo@kLb2G8m)E{ z`9v=!hi}fOytKckfN^C@6+Z*+MVI9-W_p@_3yyR#UYc0FTpD}i#k>c!wYCS)4v@E$ zchZCo=zV@)`v^$;V18ixdjFMY#q^2$wEX%{f(XD8POnsn$bpbClpC@hPxjzyO>pY|*pF3UU2tYcCN?rUk{Sskej70Mmu9vPwMYhO1m{AxAt(zqDT|0jP7FaX=6 V`?~}E4H^Id002ovPDHLkV1hC)G==~G literal 0 HcmV?d00001 diff --git a/src/docs/samples/basic-java/groovy/public/javascripts/hello.js b/src/docs/samples/basic-java/groovy/public/javascripts/hello.js new file mode 100644 index 00000000..209fbee5 --- /dev/null +++ b/src/docs/samples/basic-java/groovy/public/javascripts/hello.js @@ -0,0 +1,3 @@ +if (window.console) { + console.log("Welcome to your Play application's JavaScript!"); +} \ No newline at end of file diff --git a/src/docs/samples/basic-java/groovy/public/stylesheets/main.css b/src/docs/samples/basic-java/groovy/public/stylesheets/main.css new file mode 100644 index 00000000..e69de29b diff --git a/src/docs/samples/basic-java/groovy/settings.gradle b/src/docs/samples/basic-java/groovy/settings.gradle new file mode 100644 index 00000000..ae47080a --- /dev/null +++ b/src/docs/samples/basic-java/groovy/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'basic-java' diff --git a/src/docs/samples/basic-java/groovy/test/ApplicationSpec.scala b/src/docs/samples/basic-java/groovy/test/ApplicationSpec.scala new file mode 100644 index 00000000..e1597870 --- /dev/null +++ b/src/docs/samples/basic-java/groovy/test/ApplicationSpec.scala @@ -0,0 +1,47 @@ +import com.google.common.collect.Lists +import org.apache.commons.lang.StringUtils +import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner +import org.scalatestplus.play.PlaySpec +import org.scalatestplus.play.guice.GuiceOneAppPerSuite +import play.api.http.Status +import play.api.test.FakeRequest +import play.api.test.Helpers._ + +@RunWith(classOf[JUnitRunner]) +class ApplicationSpec extends PlaySpec with GuiceOneAppPerSuite { + + "Application" should { + + "send 404 on a bad request" in { + route(app, FakeRequest(GET, "/boum")).map(status(_)) mustBe Some(NOT_FOUND) + } + + "render the index page" in { + val home = route(app, FakeRequest(GET, "/")).get + + status(home) mustBe Status.OK + contentType(home) mustBe Some("text/html") + contentAsString(home) must include ("Your new application is ready.") + } + + "render the index page with a Java form" in { + val home = route(app, FakeRequest(GET, "/?username=testuser&mobile=987654321")).get + + status(home) mustBe Status.OK + contentType(home) mustBe Some("text/html") + contentAsString(home) must include ("Your new application is ready.") + contentAsString(home) must include ("""
""") + contentAsString(home) must include ("""""") + contentAsString(home) must include ("""""") + } + + "tests can use commons-lang play dependency" in { + StringUtils.reverse("foobar") mustBe "raboof" + } + + "tests can use guava play-test dependency" in { + Lists.newArrayList("foo", "bar").size() mustBe 2 + } + } +} diff --git a/src/docs/samples/basic-java/groovy/test/IntegrationSpec.scala b/src/docs/samples/basic-java/groovy/test/IntegrationSpec.scala new file mode 100644 index 00000000..c09b83f1 --- /dev/null +++ b/src/docs/samples/basic-java/groovy/test/IntegrationSpec.scala @@ -0,0 +1,22 @@ +import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner +import org.scalatestplus.play._ +import org.scalatestplus.play.guice.GuiceOneServerPerTest + +@RunWith(classOf[JUnitRunner]) +class IntegrationSpec extends PlaySpec + with OneBrowserPerTest + with GuiceOneServerPerTest + with HtmlUnitFactory + with ServerProvider { + + "Application" should { + + "work from within a browser" in { + + go to ("http://localhost:" + port) + + pageSource must include ("Your new application is ready.") + } + } +} diff --git a/src/docs/samples/basic/groovy/app/controllers/Application.scala b/src/docs/samples/basic/groovy/app/controllers/Application.scala index 51d64f16..0d5acfe9 100644 --- a/src/docs/samples/basic/groovy/app/controllers/Application.scala +++ b/src/docs/samples/basic/groovy/app/controllers/Application.scala @@ -7,7 +7,7 @@ import play.api.mvc._ import org.apache.commons.lang.StringUtils @Singleton -class Application @Inject() extends InjectedController { +public class Application @Inject() extends InjectedController { def index = Action { Ok(views.html.index(StringUtils.trim(" Your new application is ready. "))) From 64753a54480a8b6afc834f0265f7858214163c37 Mon Sep 17 00:00:00 2001 From: ryan Date: Sat, 9 Nov 2019 16:58:57 +0800 Subject: [PATCH 2/2] Remove the typo in Application.scala --- src/docs/samples/basic/groovy/app/controllers/Application.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/samples/basic/groovy/app/controllers/Application.scala b/src/docs/samples/basic/groovy/app/controllers/Application.scala index 0d5acfe9..51d64f16 100644 --- a/src/docs/samples/basic/groovy/app/controllers/Application.scala +++ b/src/docs/samples/basic/groovy/app/controllers/Application.scala @@ -7,7 +7,7 @@ import play.api.mvc._ import org.apache.commons.lang.StringUtils @Singleton -public class Application @Inject() extends InjectedController { +class Application @Inject() extends InjectedController { def index = Action { Ok(views.html.index(StringUtils.trim(" Your new application is ready. ")))