我们说我有这样的DSL
setup {name = "aDSLScript"}
println "this is common groovy code"
doStuff {println "I'm doing dsl stuff"}
可以有一个授权类来实现方法' setup'和' doStuff'通常。在旁边,可以编写要执行的常见Groovy代码(println ...)。
我正在寻找的是一种分两步执行的方法。在第一步中,只应处理设置方法(既不是println)。第二步处理其他部分。
目前,我有两个委派课程。一个实现'设置'另一个实现' doStuff'。但是当然都执行println语句。
答案 0 :(得分:1)
您可以创建一个类来拦截脚本中的方法调用,并让它协调以下方法调用。我是通过反思来做到的,但如果你愿意,你可以去声明。这些是模型和脚本类:
class FirstDelegate {
def setup(closure) { "firstDelegate.setup" }
}
class SecondDelegate {
def doStuff(closure) { "secondDelegate.doStuff" }
}
class MethodInterceptor {
def invokedMethods = []
def methodMissing(String method, args) {
invokedMethods << [method: method, args: args]
}
def delegate() {
def lookupCalls = { instance ->
def invokes = instance.metaClass.methods.findResults { method ->
invokedMethods.findResult { invocation ->
invocation.method == method.name ?
[method: method, invocation: invocation] : null
}
}
invokes.collect { invoked ->
invoked.method.invoke(instance, invoked.invocation.args)
}
}
return lookupCalls(new FirstDelegate()) + lookupCalls(new SecondDelegate())
}
}
这是脚本和断言:
import org.codehaus.groovy.control.CompilerConfiguration
def dsl = '''
setup {name = "aDSLScript"}
println "this is common groovy code"
doStuff {println "Ima doing dsl stuff"}
'''
def compiler = new CompilerConfiguration()
compiler.scriptBaseClass = DelegatingScript.class.name
def shell = new GroovyShell(this.class.classLoader, new Binding(), compiler)
script = shell.parse dsl
interceptor = new MethodInterceptor()
script.setDelegate interceptor
script.run()
assert interceptor.invokedMethods*.method == [ 'setup', 'doStuff' ]
assert interceptor.delegate() ==
['firstDelegate.setup', 'secondDelegate.doStuff']
请注意,我没有打扰println
拦截DefaultGroovyMethods
,因此处理起来会更加麻烦。
同时让MethodInterceptor
类实现方法delegate()
不是一个好主意,因为这允许用户定义的脚本来调用它。