Groovy - 如何反映来自另一个 groovy 应用程序的代码以在其中找到 Classes/Properties/Types
Groovy - How to reflect code from another groovy app to find Classes/Properties/Types within
首先,我有 .NET 背景,所以请原谅我缺乏 groovy 行话。当我在 .NET 商店时,我们使用 TypeScript 和 C# 来构建 Web 应用程序。在我们的控制器中,我们总是 receive/respond 使用 DTO(数据 xfer 对象)。每当你 create/modify 一个 DTO 时,你必须更新与之对应的 TypeScript 接口(d.ts 文件),这一定是一件令人头疼的事情。
所以我们创建了一个小应用程序(一个简单的 exe),它将 dll 从 webapp 加载到其中,然后反射它以找到 DTO(按特定名称空间过滤),并通过它们解析以找到每个 class 中的名称、它们的属性以及它们的属性的数据类型,将这些信息生成一个字符串,最后保存到一个 d.ts 文件中。
此应用随后在每次构建网站时都配置为 运行。这样,当您访问 run/debug/build 网站时,它会自动更新您的 d.ts 文件 - 这使得使用 TypeScript 变得更加容易。
长话短说,如果我要编写一个简单的 groovy 应用程序来生成我想要的 d.ts,我如何通过 Grails 网站实现这一点?
-- 或--
我如何将 IDE(ex IntelliJ)转换为 运行 生成这一代 post- 的 groovy 文件(即应用程序的一部分)构建?
我确实找到了这个,但仍然需要一种在编译时 运行 的方法:
Groovy property iteration
class Foo {
def feck = "fe"
def arse = "ar"
def drink = "dr"
}
class Foo2 {
def feck = "fe2"
def arse = "ar2"
def drink = "dr2"
}
def f = new Foo()
def f2 = new Foo2()
f2.properties.each { prop, val ->
if(prop in ["metaClass","class"]) return
if(f.hasProperty(prop)) f[prop] = val
}
assert f.feck == "fe2"
assert f.arse == "ar2"
assert f.drink == "dr2"
我已经能够通过以下 Gant 脚本提取域对象及其 持久性 字段:
在scripts/Props.groovy:
import static groovy.json.JsonOutput.*
includeTargets << grailsScript("_GrailsBootstrap")
target(props: "Lists persistent properties for each domain class") {
depends(loadApp)
def propMap = [:].withDefault { [] }
grailsApp.domainClasses.each {
it?.persistentProperties?.each { prop ->
if (prop.hasProperty('name') && prop.name) {
propMap[it.clazz.name] << ["${prop.name}": "${prop.getType()?.name}"]
}
}
}
// do any necessary file I/O here (just printing it now as an example)
println prettyPrint(toJson(propMap))
}
setDefaultTarget(props)
这可以通过命令行 运行 像这样:
grails props
产生如下输出:
{
"com.mycompany.User": [
{ "type": "java.lang.String" },
{ "username": "java.lang.String" },
{ "password": "java.lang.String" }
],
"com.mycompany.Person": [
{ "name": "java.lang.String" },
{ "alive": "java.lang.Boolean" }
]
}
这种方法的几个缺点是我们没有获得任何瞬态属性,而且我不确定如何将其连接到 _Events.groovy eventCompileEnd 事件中。
谢谢凯文!只是想提一下,为了达到 运行,这里有一些我必须确保在我的案例中执行的步骤,我认为我会分享:
-> 打开grails BuildConfig.groovy
-> 将 tomcat 从构建更改为编译,如下所示:
plugins {
compile ":tomcat:[version]"
}
-> 将您的 Props.groovy 放入根目录下的脚本文件夹中(注意 grails-app 文件夹的路径以供参考)
[application root]/scripts/Props.groovy
[application root]/grails-app
-> 打开终端
gvm use grails [version]
grails compile
grails Props
注意:我使用 Grails 2.3.11 进行 运行 的项目。
这让你脚本中的所有内容都对我来说 运行 成功了。现在修改println部分生成Typescript接口。
post 准备好后会 github link 所以一定要回来查看。
首先,我有 .NET 背景,所以请原谅我缺乏 groovy 行话。当我在 .NET 商店时,我们使用 TypeScript 和 C# 来构建 Web 应用程序。在我们的控制器中,我们总是 receive/respond 使用 DTO(数据 xfer 对象)。每当你 create/modify 一个 DTO 时,你必须更新与之对应的 TypeScript 接口(d.ts 文件),这一定是一件令人头疼的事情。
所以我们创建了一个小应用程序(一个简单的 exe),它将 dll 从 webapp 加载到其中,然后反射它以找到 DTO(按特定名称空间过滤),并通过它们解析以找到每个 class 中的名称、它们的属性以及它们的属性的数据类型,将这些信息生成一个字符串,最后保存到一个 d.ts 文件中。
此应用随后在每次构建网站时都配置为 运行。这样,当您访问 run/debug/build 网站时,它会自动更新您的 d.ts 文件 - 这使得使用 TypeScript 变得更加容易。
长话短说,如果我要编写一个简单的 groovy 应用程序来生成我想要的 d.ts,我如何通过 Grails 网站实现这一点?
-- 或--
我如何将 IDE(ex IntelliJ)转换为 运行 生成这一代 post- 的 groovy 文件(即应用程序的一部分)构建?
我确实找到了这个,但仍然需要一种在编译时 运行 的方法:
Groovy property iteration
class Foo { def feck = "fe" def arse = "ar" def drink = "dr" } class Foo2 { def feck = "fe2" def arse = "ar2" def drink = "dr2" } def f = new Foo() def f2 = new Foo2() f2.properties.each { prop, val -> if(prop in ["metaClass","class"]) return if(f.hasProperty(prop)) f[prop] = val } assert f.feck == "fe2" assert f.arse == "ar2" assert f.drink == "dr2"
我已经能够通过以下 Gant 脚本提取域对象及其 持久性 字段:
在scripts/Props.groovy:
import static groovy.json.JsonOutput.*
includeTargets << grailsScript("_GrailsBootstrap")
target(props: "Lists persistent properties for each domain class") {
depends(loadApp)
def propMap = [:].withDefault { [] }
grailsApp.domainClasses.each {
it?.persistentProperties?.each { prop ->
if (prop.hasProperty('name') && prop.name) {
propMap[it.clazz.name] << ["${prop.name}": "${prop.getType()?.name}"]
}
}
}
// do any necessary file I/O here (just printing it now as an example)
println prettyPrint(toJson(propMap))
}
setDefaultTarget(props)
这可以通过命令行 运行 像这样:
grails props
产生如下输出:
{
"com.mycompany.User": [
{ "type": "java.lang.String" },
{ "username": "java.lang.String" },
{ "password": "java.lang.String" }
],
"com.mycompany.Person": [
{ "name": "java.lang.String" },
{ "alive": "java.lang.Boolean" }
]
}
这种方法的几个缺点是我们没有获得任何瞬态属性,而且我不确定如何将其连接到 _Events.groovy eventCompileEnd 事件中。
谢谢凯文!只是想提一下,为了达到 运行,这里有一些我必须确保在我的案例中执行的步骤,我认为我会分享:
-> 打开grails BuildConfig.groovy
-> 将 tomcat 从构建更改为编译,如下所示:
plugins {
compile ":tomcat:[version]"
}
-> 将您的 Props.groovy 放入根目录下的脚本文件夹中(注意 grails-app 文件夹的路径以供参考)
[application root]/scripts/Props.groovy
[application root]/grails-app
-> 打开终端
gvm use grails [version]
grails compile
grails Props
注意:我使用 Grails 2.3.11 进行 运行 的项目。
这让你脚本中的所有内容都对我来说 运行 成功了。现在修改println部分生成Typescript接口。
post 准备好后会 github link 所以一定要回来查看。