简体   繁体   English

使用Java的Groovy DSL

[英]Groovy DSL with Java

It has been a couple of days since I started with Groovy. 自从我开始使用Groovy以来已经过了几天。 But with all the reading and surfing, I haven't quite been able to figure out how to accomplish what I have in mind. 但是,通过所有的阅读和冲浪,我还无法弄清楚如何实现自己的想法。 So, please excuse me as a beginner. 所以,请原谅我。 Would be much grateful for your help, as always. 一如既往地感谢您的帮助。

What I want to achieve is this : I have a Java class, say ServiceClass that has some methods ( getMethod() , postMethod() etc) to make some REST GET/POST requests (on its own, it works fine). 我要实现的目标是 :我有一个Java类,例如ServiceClass ,它具有一些方法( getMethod()postMethod()等)来发出一些REST GET / POST请求( postMethod()运行就可以了)。 Now, I want to expose a DSL so that the end-user may just say something like: callService ServiceClass method getMethod and I have the execution of ServiceClass.getMethod() 现在,我想公开一个DSL,以便最终用户可以像这样说: callService ServiceClass method getMethod然后执行ServiceClass.getMethod()

What I have been trying so far is this: I got a userCommand file placed somewhere, that for now just reads: callService ServiceClass 到目前为止,我一直在尝试以下操作:我将一个userCommand文件放在某个位置,该文​​件现在读取为: callService ServiceClass

I have a sample.groovy that just does this now: 我有一个sample.groovy现在就可以做到:

class Sample {
    def srvc
    def callService(srvc) {
        this.srvc = srvc
        "Calling $srvc"
    }
}

I got an integrator.groovy file that has: 我得到了一个具有以下内容的integrator.groovy文件:

//necessary imports
class Integrator{
    def sample = new Sample()
    def binding = new Binding([
        sample:sample, 
        ServiceClass: new ServiceClass(), 
        callService:sample.&callService ])
    def shell = new GroovyShell(binding)

    def runIt() {
        shell.evaluate("userCommand")
    }
}

And then to run it from my Java application, I am doing: 然后从我的Java应用程序运行它,我正在做:

public static void main(String[] args) {
    Integator i = new Integrator()
    i.runIt();
}

But this is just not working. 但这是行不通的。 With the above syntax it says: 使用以上语法,它表示:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke method setVariable() on null object.... 线程“主”中的异常java.lang.NullPointerException:无法在空对象上调用方法setVariable()。

Could anyone please tell me how do I pass around parameters and create object instances? 谁能告诉我如何传递参数并创建对象实例?

Update : Consider the following userCommand file: 更新 :考虑以下userCommand文件:

File userCommand : 文件userCommand

callService ServiceClass getMethod

Which will be parsed by groovy as callService(ServiceClass).getGetMethod() . 它将由groovy解析为callService(ServiceClass).getGetMethod() So you need a getProperty method which reroute the call to the correct method: 因此,您需要一个getProperty方法,该方法将调用重新路由到正确的方法:

File Dsl.groovy : 文件Dsl.groovy

class Dsl {
  static void main(args) {
      new Integrator().runIt()
  }
}

class DslDelegate {
    def service
    def callService(service) {
        this.service = service
        this
    }

    def getProperty(String prop) {
      if (prop == "getMethod") { service.getMethod() }
      else { throw new RuntimeException("Unrecognized property '$prop'") }
    }
}

class ServiceClass {
  def getMethod() { "serviceClass getMethod" }
}

class Integrator{
    def dslDelegate = new DslDelegate()
    def binding = new Binding([
        ServiceClass: new ServiceClass(), 
        callService:dslDelegate.&callService ])
    def shell = new GroovyShell(binding)

    def runIt() {
        assert shell.evaluate(new File("userCommand")) == 
            "serviceClass getMethod"
    }
}

Note I renamed the Sample class, so it becomes a delegator to ServiceClass . 注意,我重命名了Sample类,因此它成为ServiceClass的委托。 Now it separates DSL/Service responsibilities. 现在,它将DSL /服务职责分开。

You can do callService ServiceClass method getMethod too, but it requires more code. 您也可以使用callService ServiceClass method getMethod ,但需要更多代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM