具有Groovy BuilderSupport的外部内容
通过扩展BuilderSupport,我在Groovy中构建了一个自定义生成器。与几乎所有的构建器代码示例一样,它在配置时工作良好:具有Groovy BuilderSupport的外部内容,groovy,builder,Groovy,Builder,通过扩展BuilderSupport,我在Groovy中构建了一个自定义生成器。与几乎所有的构建器代码示例一样,它在配置时工作良好: def builder = new MyBuilder() builder.foo { "Some Entry" (property1:value1, property2: value2) } 当然,这是完美的。问题是我不希望我正在构建的信息出现在代码中。我希望将这些信息保存在一个文件中,该文件由生成器读入并内置到对象中。我不知道怎么做 我甚至不能通过在
def builder = new MyBuilder()
builder.foo {
"Some Entry" (property1:value1, property2: value2)
}
当然,这是完美的。问题是我不希望我正在构建的信息出现在代码中。我希望将这些信息保存在一个文件中,该文件由生成器读入并内置到对象中。我不知道怎么做
我甚至不能通过在代码中移动简单的条目来实现这一点。
这项工作:
def textClosure = { "Some Entry" (property1:value1, property2: value2) }
builder.foo(textClosure)
因为textClosure是一个闭包
如果我这样做:
def text = '"Some Entry" (property1:value1, property2: value2)'
def textClosure = { text }
builder.foo(textClosure)
生成器只为“foo”节点调用。我已经尝试了许多变体,包括直接将文本块传递到构建器中,而不将其包装在闭包中。它们都产生相同的结果
有没有什么方法可以将一段任意文本传递到我的生成器中,以便它能够正确地解析和构建它?我认为使用slurper或解析器可以更好地解决您描述的问题 见: 用于基于XML的示例 就你而言。给定XML文件:
<foo>
<entry name='Some Entry' property1="value1" property2="value2"/>
</foo>
最初,我希望能够指定
"Some Entry" (property1:value1, property2: value2)
在外部文件中。我特别尝试避免使用XML和类似XML的语法,以便普通用户更容易创建和修改这些文件。我当前的解决方案使用ConfigSlurper
,该文件现在看起来像:
"Some Entry"
{
property1 = value1
property2 = value2
}
ConfigSlurper
为我提供了如下映射:
["Some Entry":[property1:value1,property2:value2]]
使用这些值创建对象非常简单,特别是因为我可以将属性/值映射传递到构造函数中。您的问题是字符串不是Groovy代码。
ConfigSlurper
处理此问题的方法是使用GroovyClassLoader\parseClass
将文本编译成Script
的实例。e、 g
// create a Binding subclass that delegates to the builder
class MyBinding extends Binding {
def builder
Object getVariable(String name) {
return { Object... args -> builder.invokeMethod(name,args) }
}
}
// parse the script and run it against the builder
new File("foo.groovy").withInputStream { input ->
Script s = new GroovyClassLoader().parseClass(input).newInstance()
s.binding = new MyBinding(builder:builder)
s.run()
}
的子类只返回所有变量的闭包,这些变量将调用委托给生成器。因此,假设foo.groovy包含:
foo {
"Some Entry" (property1:value1, property2: value2)
}
这与上面的代码相当。这些示例仍然假设要解析/slurped的内容在类路径中,而我的应用程序则不这样。我不想在配置中使用XML—我查看了XmlSlurper和XmlParser的源代码,它们都非常特定于XML。我必须从头开始编写我的slurper/解析器,因为没有像BuilderSupport那样的公共基础。我加了一个例子来说明我的意思。也许你可以指出这个解决方案的问题所在。
foo {
"Some Entry" (property1:value1, property2: value2)
}