SBT 如何使用 DataNucleus 从模型 类 生成元模型 类?
How can SBT generate metamodel classes from model classes using DataNucleus?
如何从持久性模型 类(如客户端、产品、发票)生成元模型 类(如 QClient、QProduct、QInvoice),以便可以使用 JDOQL 类型安全查询?
特别是,我对通过 SBT 生成元模型 类 以及 运行 持久性字节码增强 类 以及使用 DataNucleus 和 JDO 注释感兴趣。
这个问题与
相关
简而言之,您需要在 build.sbt
中定义执行元模型生成和字节码增强的函数,如下所示:
def generateQueryEntities(sourcepath: File,
sources: Seq[File],
generated: File,
classes: File,
classpath: Seq[File],
javacOptions: Seq[String]): Seq[File] = {
IO.createDirectory(generated)
javaRunner(
javaTool = Option("javac"),
args =
javacOptions ++
(if(debug) Seq("-verbose") else Seq.empty[String]) ++
Seq(
"-sourcepath", sourcepath.absolutePath,
"-s", generated.absolutePath,
"-d", classes.absolutePath) ++
sources.map(p => p.absolutePath),
classpath = Option(classpath),
cwd = Option(classes)
)
classes.listFiles.filter(f => f.isFile && (f.ext == "class"))
}
def enhanceSchema(classes: File, classpath: Seq[File]): Seq[File] = {
javaRunner(
mainClass = Option("javax.jdo.Enhancer"),
args =
(if(debug) Seq("-v") else Seq.empty[String]) ++
Seq(
"-pu", "code-generation",
"-d", classes.absolutePath),
classpath = Option(classpath),
cwd = Option(classes)
)
classes.listFiles.filter(f => f.isFile && (f.ext == "class"))
}
下一步是为这些函数定义自定义任务。我们只需要 genjdoql
如下所示,因为字节码增强可以通过子任务 manipulateBytecode
连接。请注意,需要 SBT 0.13.8
或更高版本。
val genjdoql = TaskKey[Seq[File]]("genjdoql", "DataNucleus JDOQL Entities")
然后您需要在项目或模块的构建中连接这些函数,如下所示:
lazy val model =
project.in(file("model"))
.settings(publishSettings:_*)
.settings(librarySettings:_*)
.settings(paranoidOptions:_*)
.settings(otestFramework: _*)
.settings(deps_resolvers:_*)
//XXX .settings(deps_langtools:_*)
.settings(deps_tagging:_*)
.settings(deps_stream:_*)
.settings(deps_database:_*)
.settings(managedSources:_*)
.settings(
Seq(
// generate JDOQL Entities
genjdoql in Compile := {
generateQueryEntities(
sourcepath = (javaSource in Compile).value,
sources = (unmanagedSources in Compile).value,
generated = baseDirectory.value / "target" / scalav(scalaVersion.value) / "src_managed" / "main" / "java",
classes = (classDirectory in Compile).value,
classpath = (managedClasspath in Compile).value.files,
javacOptions = javacOpts :+ "-AqueryMode=PROPERTY"
)},
sourceGenerators in Compile <+= genjdoql in Compile,
// prevent javac from running annotation processors
javacOptions ++= Seq( "-proc:none" ),
// perform bytecode enhancement
manipulateBytecode in Compile := {
val previous = (manipulateBytecode in Compile).value
enhanceSchema(
classes = (classDirectory in Compile).value,
classpath =
(managedClasspath in Compile).value.files ++
(unmanagedResourceDirectories in Compile).value :+
(classDirectory in Compile).value)
previous
}
):_*)
.dependsOn(util)
如何从持久性模型 类(如客户端、产品、发票)生成元模型 类(如 QClient、QProduct、QInvoice),以便可以使用 JDOQL 类型安全查询?
特别是,我对通过 SBT 生成元模型 类 以及 运行 持久性字节码增强 类 以及使用 DataNucleus 和 JDO 注释感兴趣。
这个问题与
相关
简而言之,您需要在 build.sbt
中定义执行元模型生成和字节码增强的函数,如下所示:
def generateQueryEntities(sourcepath: File,
sources: Seq[File],
generated: File,
classes: File,
classpath: Seq[File],
javacOptions: Seq[String]): Seq[File] = {
IO.createDirectory(generated)
javaRunner(
javaTool = Option("javac"),
args =
javacOptions ++
(if(debug) Seq("-verbose") else Seq.empty[String]) ++
Seq(
"-sourcepath", sourcepath.absolutePath,
"-s", generated.absolutePath,
"-d", classes.absolutePath) ++
sources.map(p => p.absolutePath),
classpath = Option(classpath),
cwd = Option(classes)
)
classes.listFiles.filter(f => f.isFile && (f.ext == "class"))
}
def enhanceSchema(classes: File, classpath: Seq[File]): Seq[File] = {
javaRunner(
mainClass = Option("javax.jdo.Enhancer"),
args =
(if(debug) Seq("-v") else Seq.empty[String]) ++
Seq(
"-pu", "code-generation",
"-d", classes.absolutePath),
classpath = Option(classpath),
cwd = Option(classes)
)
classes.listFiles.filter(f => f.isFile && (f.ext == "class"))
}
下一步是为这些函数定义自定义任务。我们只需要 genjdoql
如下所示,因为字节码增强可以通过子任务 manipulateBytecode
连接。请注意,需要 SBT 0.13.8
或更高版本。
val genjdoql = TaskKey[Seq[File]]("genjdoql", "DataNucleus JDOQL Entities")
然后您需要在项目或模块的构建中连接这些函数,如下所示:
lazy val model =
project.in(file("model"))
.settings(publishSettings:_*)
.settings(librarySettings:_*)
.settings(paranoidOptions:_*)
.settings(otestFramework: _*)
.settings(deps_resolvers:_*)
//XXX .settings(deps_langtools:_*)
.settings(deps_tagging:_*)
.settings(deps_stream:_*)
.settings(deps_database:_*)
.settings(managedSources:_*)
.settings(
Seq(
// generate JDOQL Entities
genjdoql in Compile := {
generateQueryEntities(
sourcepath = (javaSource in Compile).value,
sources = (unmanagedSources in Compile).value,
generated = baseDirectory.value / "target" / scalav(scalaVersion.value) / "src_managed" / "main" / "java",
classes = (classDirectory in Compile).value,
classpath = (managedClasspath in Compile).value.files,
javacOptions = javacOpts :+ "-AqueryMode=PROPERTY"
)},
sourceGenerators in Compile <+= genjdoql in Compile,
// prevent javac from running annotation processors
javacOptions ++= Seq( "-proc:none" ),
// perform bytecode enhancement
manipulateBytecode in Compile := {
val previous = (manipulateBytecode in Compile).value
enhanceSchema(
classes = (classDirectory in Compile).value,
classpath =
(managedClasspath in Compile).value.files ++
(unmanagedResourceDirectories in Compile).value :+
(classDirectory in Compile).value)
previous
}
):_*)
.dependsOn(util)