如何在 Grails 插件中实现 Groovy 全局 AST 转换?

2023-12-15

我想在编译时修改一些 Grails 域类。我最初认为这是 Groovy 的全局 ASTTransformation 的工作,因为我不想注释我的域类(本地转换器需要)。最好的方法是什么?

我也尝试模仿DefaultGrailsDomainClassInjector.java通过在同一个包中创建我自己的类,实现相同的接口,但我可能只是不知道如何将其打包在正确的位置,因为我从未见过我的方法被调用。

另一方面,我能够手动创建一个 JAR,其中包含已编译的 AST 转换类,以及普通 Groovy 全局转换所需的 META-INF/服务工件。我将该 JAR 放入项目的“lib”目录中,并成功调用了 Visit()。显然,这是一项草率的工作,因为我希望在 Grails 插件中拥有 AST 转换的源代码,并且如果不需要的话,不需要单独的 JAR 工件,而且我无法通过使用这种方法来工作我的 Grails 插件的“lib”中的 JAR,但必须将其放入 Grails 应用程序的“lib”中。

这篇文章也有一点帮助:Grails 2.1.1 - 如何使用 AstTransformer 开发插件?


关于全局转换的事情是,转换代码应该在编译开始时可用。我首先要做的就是将变压器放在罐子里!但正如你所说,这是一项草率的工作。 你想要做的是让你的 ast 转换类在其他人进入编译阶段之前编译。这就是你要做的!

准备变压器

创建一个名为的目录precompiled in src文件夹!并以正确的打包结构在此目录中添加 Transformation 类和转换器使用的类(例如注释)。

然后创建一个名为org.codehaus.groovy.transform.ASTTransformation在被称为precompiled/META-INF/services你将拥有以下结构。

precompiled
--amanu
----LoggingASTTransformation.groovy
--META-INF
----services
------org.codehaus.groovy.transform.ASTTransformation

然后在变压器的完全限定名称中写入org.codehaus.groovy.transform.ASTTransformation文件,对于上面的示例,完全限定名称将是amanu.LoggingASTTransformation

执行

package amanu 

import org.codehaus.groovy.transform.GroovyASTTransformation 
import org.codehaus.groovy.transform.ASTTransformation 
import org.codehaus.groovy.control.CompilePhase 
import org.codehaus.groovy.ast.ASTNode 
import org.codehaus.groovy.control.SourceUnit 

@GroovyASTTransformation(phase=CompilePhase.CANONICALIZATION) 
class TeamDomainASTTransformation implements ASTTransformation{ 

   public void visit(ASTNode[] nodes, SourceUnit sourceUnit) { 
       println ("*********************** VISIT ************")
       source.getAST()?.getClasses()?.each { classNode -> 
          //Class node is a class that is contained in the file being compiled
          classNode.addProperty("filed", ClassNode.ACC_PUBLIC, new ClassNode(Class.forName("java.lang.String")), null, null, null)
       }
   } 
} 

汇编

实施此操作后,您可以通过两种方式出发!第一种方法是将其放入罐子中,就像您一样!另一种是使用groovy脚本先于其他人编译它。为了在 grails 中做到这一点,我们使用_Events.groovy script.

您可以从插件或主项目中执行此操作,这并不重要。如果不存在,创建一个名为_Events.groovy并添加以下内容。

代码复制自莱因哈德-塞勒.blogspot.com有修改

eventCompileStart = {target ->  
    ...
    compileAST(pluginBasedir, classesDirPath)  
    ...
  }  
  def compileAST(def srcBaseDir, def destDir) {  
   ant.sequential {  
      echo "Precompiling AST Transformations ..."  
      echo "src ${srcBaseDir} ${destDir}"  
      path id: "grails.compile.classpath", compileClasspath  
      def classpathId = "grails.compile.classpath"  
      mkdir dir: destDir  
      groovyc(destdir: destDir,  
          srcDir: "$srcBaseDir/src/precompiled",  
          classpathref: classpathId,  
          stacktrace: "yes",  
          encoding: "UTF-8")
     copy(toDir:"$destDir/META-INF"){
        fileset(dir:"$srcBaseDir/src/precompiled/META-INF")
     }  
      echo "done precompiling AST Transformations"  
    }  
}  

前面的脚本将在编译其他脚本之前编译转换器!这使得转换器可用于转换您的域类。

别忘了

如果您使用类路径中添加的类以外的任何类,则也必须预编译它们。上面的脚本将编译所有内容precompiled目录,您还可以添加不需要 ast 但在该目录中需要它的类!

如果您想在转换中使用域类,您可能需要在以下位置进行预编译evenCompileEnd堵塞!但这会让事情变得更慢!

Update

@Douglas Mendes 提到有一种简单的方法可以进行预编译。哪个更简洁。

eventCompileStart = { 
   target -> projectCompiler.srcDirectories.add(0, "./src/precompiled") 
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Grails 插件中实现 Groovy 全局 AST 转换? 的相关文章

  • 遍历多行字符串

    我得到一些数据 def data some useless text n even more n finally interesting text 我怎样才能得到其中 有趣的部分 所以基本上所有行都不是以 开头的 Groovy 的一种选择是
  • Groovy 与 Grape 和 AntBuilder 类加载器问题

    我想使用 groovy 编写一个小 ftp 脚本 并找到了这篇文章http www hhhhq org blog 2009 05 01 ftp using groovy and ant http www hhhhq org blog 200
  • groovy 无法解析 kotlin 类

    由于我无法解决我遇到的问题kotlin 我决定回到groovy为了实现该插件 但是我遇到了这个问题 我有这样的项目结构 为了不重写所有类 我决定重用中实现的类kotlin 然而我的课FileProcessingCoreGroovy Down
  • grails postgres 消息:错误:列 this_.id 不存在

    grails 和 postgres 用于用户域 Message ERROR column this id does not exist 明白问题了 对于用户域 我将 postgres 表设置为 用户 因此 默认情况下 当它尝试查询用户表时
  • 如何在 Groovy 中的 JSON Converter 方法中保留字母大小写?

    我正在尝试将 groovy 对象解析为 JSON 属性名称不遵循正确的驼峰式大小写形式 class Client String Name Date Birthdate 当我使用这个时 Client client new Client Nam
  • Intellij groovy:错误:无法编译 Groovy 文件:没有为模块“groovyTest”定义 Groovy 库

    I m attempting a Hello World in Groovy using Intellij I m using the latest Intellij I installed Groovy using sdkman When
  • Grails 默认包名称

    我是 Grails 的新手 而且非常喜欢它 我想将我的课程放在像这样的包中org company project module model 重复对我来说很痛苦create domain class
  • grails 中的 log4j:如何登录文件?

    我的 grails config groovy 中有这个 log4j 配置 log4j error org codehaus groovy grails web servlet controllers org codehaus groovy
  • Grails Asset-pipeline 不加载角度部分模板

    我将 angular ui bootstrap 与 Grails 2 3 x asset pipeline 1 6 1 插件一起使用 其中一个组件 alert js 正在尝试加载 template alert alert html 但这会解
  • grails 重写重定向控制器方法

    我试图覆盖默认的控制器重定向方法 但似乎无法让以下代码正常工作 我创建了一个插件 我正在尝试使用 doWithDynamicMethods 来替换重定向 def doWithDynamicMethods ctx gt application
  • 在另一个插件中覆盖插件 GSP 和控制器

    我的项目中有一个相当复杂的 grails 插件依赖结构 并且在覆盖安全插件中的类时遇到问题 我的结构有点像这样 Web App Audit Plugin Spring Security Core Plugin Security Wrappe
  • 修改String字段的getter的返回值

    假设我的应用程序中有一些类似于域类的类 其中包含一些 Long Double Date 和 String 字段 这些类使用一些公共字段和一些公共方法扩展了基类 每当我访问 String 类字段 通过 getter 时 我想对返回的值进行一些
  • 如何在 WebStorm 中安装 Groovy 插件?

    我正在使用 WebStorm 进行开发 我想要为 Jenkins Groovy 管道提供语法突出显示 使用IntelliJ IDEA来编辑Jenkinsfile是可以的 但是在IDE之间来回切换显然很不方便 我可以安装吗Groovy 插件
  • Groovy 元编程 - 将静态方法添加到 Object.metaClass

    我遇到了无法解决的 Groovy 元编程问题 将静态方法 foo 添加到类 FooBar 时 FooBar foo 按预期工作 FooBar metaClass static foo println hello FooBar foo 但是
  • Grails 2.3.0 自动重新加载不起作用

    我最近将我们的项目升级到 grails 2 3 0 一切工作正常 除了每当我更改代码时自动重新加载都无法工作的问题 这包括所有项目工件 控制器 域 服务 gsps css 和 javascript 文件 我的旧版本 grails 可以正常工
  • 适合 .Net 开发人员的 Grails/Roo

    我目前正在学习 Grails 和 Roo 绝大多数培训材料都是针对新开发人员或现有 Java 开发人员 有谁知道使用 Net C ASP Net Asp Net MVC 翻译现有开发经验的任何指南 资源或技巧 你做过很多 ASP MVC 吗
  • 模拟 Spock 中的超类

    如何对 Spock 中具有超类的类进行单元测试 该超类调用来自其超类的方法调用 或者如何模拟 Spock 中的超类 Ex class Bar def method1 parm1 Method actions class Foo extend
  • 使用 JQuery 的 Grails 项目,无需插件

    我正在尝试设置一个简单的 Grails 2 1 1 应用程序 该应用程序将使用 JQuery 我有一个名为 TestController 的控制器和一个位于正确位置的index gsp 我手动添加 JQuery 库 没有使用 Grails
  • Grails、Spring Security Core - 从应用程序中删除 /login/auth

    我在 Grails 应用程序中安装了 Spring Security Core 并使用s2 quickstart 我想要 来处理登录和注销操作 对我来说 这意味着未登录的用户只能访问根页面 而不能访问其他页面 实际上 对于没有角色 ROLE
  • 文本在指定长度后分割,但不要使用 grails 打断单词

    我有一个长字符串 需要将其解析为长度不超过 50 个字符的字符串数组 对我来说 棘手的部分是确保正则表达式找到 50 个字符之前的最后一个空格 以便在字符串之间进行彻底的分隔 因为我不希望单词被切断 public List

随机推荐

  • 在窗口加载时通过 URL 将值传递给 JS 函数

    my page http www dinomuhic com 2010 index php使用正文中的 onLoad 调用在页面开头加载 Showreel 如下所示 96 是 SQL 库中节目卷的 ID JS 函数 sndReq 是使用 J
  • 如何通过C程序打印扩展ASCII字符127到160?

    我正在尝试下面的代码来打印所有 ASCII 字符 但它不会打印 127 到 160 的任何内容 我知道它们是控制字符集或一些拉丁 西班牙语字符 如果从Windows复制粘贴相同的字符 则在unix中打印效果很好 为什么不通过 C 程序呢 i
  • Android Studio 卡在“Gradle:解析依赖项‘_debugCompile’”或“detachedConfiguration1”上

    我不知道我在项目中更改了什么 但在构建 gradle 脚本时突然无法通过这一步 仅使用 gradle assemble 构建它是没有问题的 编辑 之前的卡点是解决依赖项 detachedConfiguration1 在第一次尝试 debug
  • AES ECB iOS 加密

    我尝试使用 AES 算法和 ECB 选项来加密一些字符串 size t bufferSize dataLength kCCBlockSizeAES128 void buffer malloc bufferSize size t numByt
  • 无法使用连接字符串连接到本地 SQL Server DB,但 VS 可以

    我正在尝试使用连接字符串通过 Visual Studio 15 连接到本地 Sql Server 2012 数据库实例 虽然我已经能够通过 Visual Studio SQL Server 对象资源管理器连接到数据库并成功运行测试过程 但我
  • bash“如果[假];”返回 true 而不是 false —— 为什么?

    为什么会输出如下True bin sh if false then echo True else echo False fi 这将始终输出True即使情况似乎表明情况并非如此 如果我去掉括号 然后它起作用了 但我不明白为什么 您正在运行 a
  • 返回列表 1 和列表 2 中的项目匹配的列表

    假设我有 2List
  • 关于清单文件中的“singleton:= true”

    我有一个插件 目前没有任何扩展点 它也不扩展任何其他插件 为了解决某个问题 我必须为此插件创建一个扩展点 并在其他地方创建一个适当的扩展 当做这个日食时迫使我设置singleton true在清单文件中 我知道必须设置此参数的原因 但我想知
  • 检查字符串中所有字符是否相等的函数 javascript - 作业警告

    我找到了这个作业问题的解决方案 但我不认为这是解决问题的最有效方法 对我应该探索的其他解决方案感兴趣 问题 编写一个名为 allEqual 的函数 如果字符串中的每个字符都相同 则返回 true Example 如果你传递 aaa 它应该返
  • 重绘中的图形绘制随机线条

    因此 我正在创建一个手绘 JPanel 它对鼠标移动做出反应并绘制线条 我让它大部分工作 除了一个错误 它会在线条之间随机绘制一条直线 这条随机直线不是故意的 缓冲图像上绘制的内容应该严格是用户绘制的 这些随机绘制的线条不是由用户完成的 而
  • Saas:单实例、多实例、单租户、多租户?

    我一直在阅读有关实例和租户以及 Saas 架构的内容 我的问题如下 如果您发现我对以下任何术语有错误 请更正 1 实例 某个软件的实例是否只是该软件的副本及其自己的数据库 还有比这更重要的事情吗 2 Tenant 租户是对单个实例共享一组通
  • Golang 中的位掩码和按位运算

    一般来说 我是编程的初学者 所以如果我在提出这个问题时犯了一些错误 我很抱歉 我正在遵循的教程将详细介绍此代码 package main import fmt const isAdmin 1 lt lt iota isHeadquarter
  • 动画计数器从开始值到结束值

    我想在我的网站上放置一个柜台 以下代码适用于非常大的数字 但像 3 或 95 5 这样的小数字则不起作用 但它适用于超过 1000 的数字 您认为 JavaScript 代码编写的问题出在哪里 预先感谢您的指导 const counters
  • 模板专用函数

    我需要使用模板类对我的函数进行专门化 并且遇到 非法使用显式模板参数 的问题 template
  • MySQL 复合在 FK 上是独一无二的

    我想在mysql中实现以下约束 create table TypeMapping constraint unique server id type id constraint foreign key server id references
  • wicked_pdf 生产中字体太大

    我遇到一个问题 渲染的 PDF 的字体大小为产量较大 在开发中生成的 PDF 中 一切看起来都很棒 这是来自的渲染图发展 这是来自的渲染图生产 这使得我很难为开发中的生产服务器格式化我的文档 你能看一下吗 HTML 版本 http www
  • jqGrid没有addJSONData方法

    今天下午我只是在玩 jqGrid 让它与本地数组数据源配合得很好 但是 现在我正在尝试让它加载本地 JSON 数据 我的代码如下 jQuery list4 jqGrid datatype json lt Also tried local h
  • 如何使用 angularjs 关闭点击主体时动态生成的下拉菜单?

    你好 我正在 angularjs 中开发 Web 应用程序 在右上角 我有一个下拉框 只有在用户登录后才会激活 我有一个场景 用户单击下拉菜单 一旦他单击页面上的任意位置 我想关闭下拉菜单 长期以来我一直在努力解决这个问题 我创建了 plu
  • Python Mysql,“命令不同步;您现在无法运行此命令”

    我有一个从 Python 执行的 MySQL 存储过程 包装在 Django 中 当我尝试执行第二条语句时 出现错误 命令不同步 您现在无法运行此命令 我目前无法提交交易 这只是我调用过程时的一个问题 该怎么办 cursor callpro
  • 如何在 Grails 插件中实现 Groovy 全局 AST 转换?

    我想在编译时修改一些 Grails 域类 我最初认为这是 Groovy 的全局 ASTTransformation 的工作 因为我不想注释我的域类 本地转换器需要 最好的方法是什么 我也尝试模仿DefaultGrailsDomainClas