From 43887fbed1eb106630d854e06c9105771601f660 Mon Sep 17 00:00:00 2001 From: andrewlynch Date: Wed, 18 Nov 2015 13:30:10 +0700 Subject: [PATCH 1/3] Add query bean support --- .gitignore | 2 + build.sbt | 14 ++-- .../main/scala/play/ebean/sbt/PlayEbean.scala | 67 +++++++++++++++++-- 3 files changed, 73 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index a8844162..d3df77a1 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ docs/conf +/.idea + # sbt specific dist/* target/ diff --git a/build.sbt b/build.sbt index b530d813..4244d644 100644 --- a/build.sbt +++ b/build.sbt @@ -7,7 +7,7 @@ val PlayEnhancerVersion = "1.1.0" lazy val root = project .in(file(".")) .enablePlugins(PlayRootProject) - .aggregate(core) + .aggregate(core,plugin) .settings( name := "play-ebean-root", releaseCrossBuild := false @@ -45,9 +45,9 @@ lazy val plugin = project ) playBuildRepoName in ThisBuild := "play-ebean" -// playBuildExtraTests := { -// (scripted in plugin).toTask("").value -// } +playBuildExtraTests := { + (scripted in plugin).toTask("").value +} playBuildExtraPublish := { (PgpKeys.publishSigned in plugin).value } @@ -59,15 +59,21 @@ def playEbeanDeps = Seq( "com.typesafe.play" %% "play-jdbc-evolutions" % PlayVersion, "org.avaje.ebeanorm" % "avaje-ebeanorm" % "6.8.1", avajeEbeanormAgent, + avajeEbeanormQueryAgent, + avajeGenerator, "com.typesafe.play" %% "play-test" % PlayVersion % Test ) def sbtPlayEbeanDeps = Seq( avajeEbeanormAgent, + avajeEbeanormQueryAgent, + avajeGenerator, "com.typesafe" % "config" % "1.3.0" ) def avajeEbeanormAgent = "org.avaje.ebeanorm" % "avaje-ebeanorm-agent" % "4.7.1" +def avajeEbeanormQueryAgent = "org.avaje.ebeanorm" % "avaje-ebeanorm-typequery-agent" % "1.5.1" +def avajeGenerator = "org.avaje.ebeanorm" % "avaje-ebeanorm-typequery-generator" % "1.5.1" // Ebean enhancement diff --git a/sbt-play-ebean/src/main/scala/play/ebean/sbt/PlayEbean.scala b/sbt-play-ebean/src/main/scala/play/ebean/sbt/PlayEbean.scala index b293ed16..39d8e5dd 100644 --- a/sbt-play-ebean/src/main/scala/play/ebean/sbt/PlayEbean.scala +++ b/sbt-play-ebean/src/main/scala/play/ebean/sbt/PlayEbean.scala @@ -3,9 +3,11 @@ package play.ebean.sbt import java.net.URLClassLoader import com.typesafe.play.sbt.enhancer.PlayEnhancer +import org.avaje.ebean.typequery.generator.{Generator, GeneratorConfig} import sbt.Keys._ import sbt._ import sbt.inc._ +import scala.collection.JavaConverters._ import scala.util.control.NonFatal @@ -16,6 +18,19 @@ object PlayEbean extends AutoPlugin { val playEbeanVersion = settingKey[String]("The version of Play ebean that should be added to the library dependencies.") val playEbeanDebugLevel = settingKey[Int]("The debug level to use for the ebean agent. The higher, the more debug is output, with 9 being the most. -1 turns debugging off.") val playEbeanAgentArgs = taskKey[Map[String, String]]("The arguments to pass to the agent.") + + val playEbeanQueryGenerate = settingKey[Boolean]("Generate Query Beans from model classes. Default false.") + val playEbeanQueryEnhance = settingKey[Boolean]("Enhance Query Beans from model classes. Defaults to false") + val playEbeanQueryDestDirectory = settingKey[String]("Target directory for generated classes. Defaults to app ") + val playEbeanQueryResourceDirectory = settingKey[String]("Resource directory to read configuration. Defaults to conf") + val playEbeanQueryModelsPackage = settingKey[String]("Directory of models to scan to build query beans") + val playEbeanQueryModelsQueryModificationPackage = settingKey[Set[String]]("Directories of matching query objects to rewrite field access to use getters. Defaults to [model/query]") + val playEbeanQueryGenerateFinder = settingKey[Boolean]("Generate finder objects") + val playEbeanQueryGenerateFinderField = settingKey[Boolean]("Modify models to add finder field") + val playEbeanQueryGeneratePublicWhereField = settingKey[Boolean]("Public finder field") + val playEbeanQueryGenerateAopStyle = settingKey[Boolean]("Use AOP style generation. Default true") + val playEbeanQueryArgs = settingKey[String]("Args for generation, useful for logging / debugging generation ") + val playEbeanQueryProcessPackages = settingKey[String]("Change to alter the initial package for scanning for model classes. By default views all") } import autoImport._ @@ -25,7 +40,24 @@ object PlayEbean extends AutoPlugin { override def trigger = noTrigger - override def projectSettings = inConfig(Compile)(scopedSettings) ++ unscopedSettings + override def projectSettings = { + val querySettings = Seq( + playEbeanQueryGenerate := false, + playEbeanQueryEnhance := false, + playEbeanQueryDestDirectory := "app", + playEbeanQueryResourceDirectory := "conf", + playEbeanQueryModelsPackage := "models", + playEbeanQueryModelsQueryModificationPackage := Set("models/query"), + playEbeanQueryGenerateFinder := true, + playEbeanQueryGenerateFinderField := true, + playEbeanQueryGeneratePublicWhereField := true, + playEbeanQueryGenerateAopStyle := true, + playEbeanQueryArgs := "", + playEbeanQueryProcessPackages := null + ) + + inConfig(Compile)(scopedSettings) ++ unscopedSettings ++ querySettings + } def scopedSettings = Seq( playEbeanModels <<= configuredEbeanModels, @@ -61,13 +93,36 @@ object PlayEbean extends AutoPlugin { import com.avaje.ebean.enhance.agent._ import com.avaje.ebean.enhance.ant._ - - val transformer = new Transformer(classpath, agentArgsString) - - val fileTransform = new OfflineFileTransform(transformer, classLoader, classes.getAbsolutePath) - try { + if(playEbeanQueryGenerate.value) { + val config = new GeneratorConfig() + config.setClassesDirectory(classes.getAbsolutePath) + config.setDestDirectory(playEbeanQueryDestDirectory.value) + config.setDestResourceDirectory(playEbeanQueryResourceDirectory.value) + + config.setEntityBeanPackage(playEbeanQueryModelsPackage.value) + config.setAddFinderWherePublic(playEbeanQueryGeneratePublicWhereField.value) + config.setAopStyle(playEbeanQueryGenerateAopStyle.value) + + val generator: Generator = new Generator(config) + generator.generateQueryBeans() + if (playEbeanQueryGenerateFinder.value) { + generator.generateFinders() + } + if (playEbeanQueryGenerateFinderField.value) { + generator.modifyEntityBeansAddFinderField() + } + } + + val transformer = new Transformer(classpath, agentArgsString) + val fileTransform = new OfflineFileTransform(transformer, classLoader, classes.getAbsolutePath) fileTransform.process(playEbeanModels.value.mkString(",")) + if(playEbeanQueryEnhance.value) { + val queryTransform = new org.avaje.ebean.typequery.agent.Transformer(playEbeanQueryArgs.value, classLoader, playEbeanQueryModelsQueryModificationPackage.value.asJava) + val fileQueryTransform = new org.avaje.ebean.typequery.agent.offline.OfflineFileTransform(queryTransform, classLoader, classes.getAbsolutePath) + //Defaults to null, like the Maven plugin + fileQueryTransform.process(playEbeanQueryProcessPackages.value) + } } catch { case NonFatal(_) => } From f7fe853269a9172ad45837dbc8d12fa17411a3bf Mon Sep 17 00:00:00 2001 From: andrewlynch Date: Wed, 18 Nov 2015 18:00:38 +0700 Subject: [PATCH 2/3] Fix test --- .../src/main/scala/play/ebean/sbt/PlayEbean.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sbt-play-ebean/src/main/scala/play/ebean/sbt/PlayEbean.scala b/sbt-play-ebean/src/main/scala/play/ebean/sbt/PlayEbean.scala index 39d8e5dd..cd9dc0ab 100644 --- a/sbt-play-ebean/src/main/scala/play/ebean/sbt/PlayEbean.scala +++ b/sbt-play-ebean/src/main/scala/play/ebean/sbt/PlayEbean.scala @@ -30,7 +30,7 @@ object PlayEbean extends AutoPlugin { val playEbeanQueryGeneratePublicWhereField = settingKey[Boolean]("Public finder field") val playEbeanQueryGenerateAopStyle = settingKey[Boolean]("Use AOP style generation. Default true") val playEbeanQueryArgs = settingKey[String]("Args for generation, useful for logging / debugging generation ") - val playEbeanQueryProcessPackages = settingKey[String]("Change to alter the initial package for scanning for model classes. By default views all") + val playEbeanQueryProcessPackages = settingKey[Option[String]]("Change to alter the initial package for scanning for model classes. By default views all") } import autoImport._ @@ -53,7 +53,7 @@ object PlayEbean extends AutoPlugin { playEbeanQueryGeneratePublicWhereField := true, playEbeanQueryGenerateAopStyle := true, playEbeanQueryArgs := "", - playEbeanQueryProcessPackages := null + playEbeanQueryProcessPackages := None ) inConfig(Compile)(scopedSettings) ++ unscopedSettings ++ querySettings @@ -121,7 +121,7 @@ object PlayEbean extends AutoPlugin { val queryTransform = new org.avaje.ebean.typequery.agent.Transformer(playEbeanQueryArgs.value, classLoader, playEbeanQueryModelsQueryModificationPackage.value.asJava) val fileQueryTransform = new org.avaje.ebean.typequery.agent.offline.OfflineFileTransform(queryTransform, classLoader, classes.getAbsolutePath) //Defaults to null, like the Maven plugin - fileQueryTransform.process(playEbeanQueryProcessPackages.value) + fileQueryTransform.process(playEbeanQueryProcessPackages.value.orNull) } } catch { case NonFatal(_) => From a5fbc72e50bd361e710e56663c5318700f0cb0a6 Mon Sep 17 00:00:00 2001 From: andrewlynch Date: Wed, 18 Nov 2015 19:06:01 +0700 Subject: [PATCH 3/3] Fix documentation --- docs/build.sbt | 12 ++++++++++++ docs/manual/working/javaGuide/main/sql/JavaEbean.md | 7 +++++++ 2 files changed, 19 insertions(+) diff --git a/docs/build.sbt b/docs/build.sbt index cf4bc688..fba4c8e0 100644 --- a/docs/build.sbt +++ b/docs/build.sbt @@ -15,6 +15,18 @@ lazy val docs = project ) .settings(PlayEbean.unscopedSettings: _*) .settings(inConfig(Test)(Seq( + playEbeanQueryGenerate := false, + playEbeanQueryEnhance := false, + playEbeanQueryDestDirectory := "app", + playEbeanQueryResourceDirectory := "conf", + playEbeanQueryModelsPackage := "models", + playEbeanQueryModelsQueryModificationPackage := Set("models/query"), + playEbeanQueryGenerateFinder := true, + playEbeanQueryGenerateFinderField := true, + playEbeanQueryGeneratePublicWhereField := true, + playEbeanQueryGenerateAopStyle := true, + playEbeanQueryArgs := "", + playEbeanQueryProcessPackages := None, playEbeanModels := Seq("javaguide.ebean.*"), manipulateBytecode <<= PlayEbean.ebeanEnhance )): _*) diff --git a/docs/manual/working/javaGuide/main/sql/JavaEbean.md b/docs/manual/working/javaGuide/main/sql/JavaEbean.md index 25c13ff3..76340e86 100644 --- a/docs/manual/working/javaGuide/main/sql/JavaEbean.md +++ b/docs/manual/working/javaGuide/main/sql/JavaEbean.md @@ -62,6 +62,13 @@ Finally, if you want to also enhance models in your tests, you can do this by co @[play-ebean-test](code/ebean.sbt) +## Generating Typesafe query beans. + +The plugin can also be configured to generate type safe query beans. By default, this is disabled. +To enable it, set the property `playEbeanQueryGenerate` to true. You will also need to set `playEbeanQueryEnhance` to true if you wish to use enhancement with the query beans. + +Note that the Play enhancer can interfere with the use of query beans. You may need to set `playEnhancerEnabled := false` or disable package scanning of the affected classes. + ## Using Model superclass Ebean defines a convenient superclass for your Ebean model classes, `com.avaje.ebean.Model`. Here is a typical Ebean class, mapped in Play: