BuilderSupportでDSL
GroovyでDSLを作るときに便利なBuilderSupportを使う簡単な例です。
public class MyBuilder extends BuilderSupport{ protected Object createNode(Object name) { def obj = new Expando(name:name,children:,attributes:[:]) return obj } protected Object createNode(Object name, Map attributes) { def obj = new Expando(name:name,attributes:attributes,children:) return obj } protected void setParent(Object parent, Object child) { parent.children << child } protected Object createNode(Object name, Object value) { return null } protected Object createNode(Object name, Map attributes, Object value) { return null } } def builder = new MyBuilder() def ret = builder.aaa{ target01(prop1:"aaa"){ child01(name:"name01",class:"child.Child01") child02(name:"name02",class:"child.Child02") } target02(prop1:"bbb"){ child03(name:"name03",class:"child.Child03") child04(name:"name04",class:"child.Child04") } } println "$ret"
結果
{name=aaa, children=[{name=target01, attributes={prop1=aaa}, children=[{name=child01, attributes={name=name01, class=child.Child01}, children=}, {name=child02, attributes={name=name02, class=child.Child02}, children=}]}, {name=target02, attributes={prop1=bbb}, children=[{name=child03, attributes={name=name03, class=child.Child03}, children=}, {name=child04, attributes={name=name04, class=child.Child04}, children=}]}], attributes={}}
参考URL:
http://groovy.codehaus.org/Make+a+builder
BuilderSupportを継承し、abstructメソッドをオーバーライドします(サンプルに不要なメソッドは空実装にしてnullを返しています)
また、上記参考URLでは、ノードを作成するのにNodeクラスを使ってる例がありますが、値を取り出すのが面倒だったりするので、
Expandoでname,attribute,childrenだけ持ったインスタンスを作って返しています。
ノードの親子関係はsetParent()で親への追加の仕方を記述しておくとBuilderSupportが親子関係を設定してくれています。