Another important feature in Groovy is Builder. Groovy Builders allow you to create complex tree-like hierarchical object structures. For example, SwingUI or XML documents can be created very easily using the DSL or Closure-like features in Groovy, with the support of the BuilderSupport
class and its subclasses, MarkupBuilder
and SwingBuilder
.
Let's try to understand with an example. We created the Order
class earlier in this chapter. Assume we have a list of orders and we want to store the details in a file called orders.xml
. So every Order
object in our list should be saved as a node in the XML file. Each of these Order
nodes, again should contain child nodes, grand children nodes, and so on. Creating this tree-like structure can be complex if we try to implement a DOM-like parser in Java:
<orders> <order> <no>1</no> <description>Ordered by customer 1</description> <customer> <name firstname='Customer1' /> <email>[email protected]</email> </customer> </order> <order> <no>2</no> <description>Ordered by customer 2</description> <customer> <name firstname='Customer2' /> <email>[email protected]</email> </customer> </order> …. </orders>
But in Groovy, this is just few lines of code with some method calls combined with Closure and named parameters. In the following example, we have created a builder
object from the MarkupBuilder
class to create the XML document. Then we have defined orders
as the root of the document. However, builder
has no method defined as orders
. So then, how does this work?
As mentioned earlier, the MarkupBuilder
class is a subclass of the BuilderSupport
class. BuilderSupport
has methods such as createNode
, invokeMethod
, nodeCompleted
, setCurrent
, setParent
, and a few more. In runtime, an object is created by calling the createNode
method on the builder with the name orders
. In a similar fashion, for each order
object, no
, description
, and customer
nodes are created. Finally, each order
node is attached to the parent orders
node by calling the setParent
method of the builder object:
def builder = new groovy.xml.MarkupBuilder(new FileWriter("orders.xml")) builder.orders{ for(i in orderlist){ order{ no(i.orderNo) description(i.description) customer{ name(firstname : i.orderedBy.name) email(i.orderedBy.email) } } } }
3.21.106.7