Groovy Builder支持

时间:2011-09-26 06:10:09

标签: groovy closures dsl

如何使用groovy builder support

构建上述模式
emp = empFileFactory.root()
{
  emp(id: '3', value: '1')

  emp(id:'24')
  {
    emp(id: '1', value: '2')
    emp(id: '6', value: '7')
    emp(id: '7', value: '1')
  }

  emp(id: '25')
  {
    emp(id: '1', value: '1')
    emp(id: '6', value: '7')
  }

}

我正在尝试在groovy中构建上述结构,可以解释一下如何解决这个问题

2 个答案:

答案 0 :(得分:4)

你可以做这样的事情(这没有错误处理,只为我不希望被调用的方法返回null):

// First define our class to hold our created 'Emp' objects
@groovy.transform.Canonical
class Emp {
  String id
  String value
  List<Emp> children = []
}

class EmpBuilder extends BuilderSupport{
  def children = []
  protected void setParent(Object parent, Object child){
    parent.children << child
  }
  protected Object createNode(Object name){
    if( name == 'root' ) {
      this
    }
    else {
      null
    }
  }
  protected Object createNode(Object name, Object value){
    null
  }
  protected Object createNode(Object name, Map attributes){
    if( name == 'emp' ) {
      new Emp( attributes )
    }
    else {
      null
    }
  }
  protected Object createNode(Object name, Map attributes, Object value){
    null
  }
  protected void nodeCompleted(Object parent, Object node) {
  }
  Iterator iterator() { children.iterator() }
}

然后,如果我们使用您所需的构建器代码调用它,如下所示:

b = new EmpBuilder().root() {
  emp(id: '3', value: '1')

  emp(id:'24') {
    emp(id: '1', value: '2')
    emp(id: '6', value: '7')
    emp(id: '7', value: '1')
  }

  emp(id: '25') {
    emp(id: '1', value: '1')
    emp(id: '6', value: '7')
  }
}

我们可以像这样打印出“树”

b.each { println it }

看到我们得到了我们要求的结构:

Emp(3, 1, [])
Emp(24, null, [Emp(1, 2, []), Emp(6, 7, []), Emp(7, 1, [])])
Emp(25, null, [Emp(1, 1, []), Emp(6, 7, [])])

答案 1 :(得分:1)

您想要实现扩展BuilderSupport类,这很容易实现。有a pretty nice tutorial here

您需要实现一些方法,但命名应该是不言自明的:

  • createNode创建一个节点(每个节点都有一个名称和可选属性和/或值)
  • setParent将节点指定为另一个节点parent

这就是它。