Coding Groovy builders - No Fluff Just Stuff

Coding Groovy builders

Posted by: Andres Almiray on October 13, 2007

One of the first features that attracted my attention when looking at Groovy was Builders. Builders are not a language specific feature but it surely is easy to use them in a language that provides dynamic typing. Coding your own builder is also relative easy, depending on the strategy you choose, in Groovy's case you have the following options:
  • extend BuilderSupport, the "standard way", just plugin your logic
  • extend FactoryBuilderSupport, provides a factory-based abstraction over BuilderSupport.
  • extend GroovyObjectSupport, the "hard way", define your own rules.

Of the 3 options its more likely that you'll find more information on #1 (GinA has a good chapter on it) so I'll discuss the other two.

Let's start with FactoryBuilderSupport, as its name implies relies on factories to do its work, as a matter of fact it is based on how SwingBuilder works, but how does it do it? the cornerstone is groovy.util.Factory, an interface that outlines the basic contract for all factories

All methods will be called at an specific point by the builder, in fact in the following order
  • newInstance - responsible for creating the object represented by the node.
  • onHandleNodeAttributes - responsible for handling and setting any properties on the node. By returning true you specify that the factory did the appropriate handling and that the builder will not process the properties afterwards.
  • setParent - if this node is nested then this method will be called with the parent node as one of its parameter, useful for chaining nodes in a hierarchy.
  • setChild - called during the builder's setParent, may help in adjusting parent-child relationships.
  • isLeaf - if true then any child closure on this node will make the builder throw an exception.
  • onNodeCompleted - responsible for any cleanup code just before the node gets out of context.
FactoryBuilderSupport also adds context-per-node capabilities, now you can store values per node without the fear of them clashing over, it also has the following convenient methods that rely on this feature
  • getCurrent - returns the current node being built.
  • getCurrentFactory - returns the factory associated with the current node.
  • getParentFactory - returns the factory of the parent node (if any).
SwingBuilder and its offspring (SwingXBuilder and JideBuilder) have already been retrofitted to inherit from FactoryBuilderSupport, so you'll have plenty of code to study if you want to ;-)

I labeled the third option "the hard way" but in truth it will be as hard as you like, depending on the building rules your code needs. Examples of this option are BeanBuilder and HibernateCriteriaBuilder from Grails, JsonGroovyBuilder from Json-lib and the recently announced WizardBuilder from JMatter (don't mind the shameless plug), so you will also find plenty of examples to study. The point is to use the fact that all method calls in a GroovyObject are routed through invokeMethod, serving as a hub for your 'pretended' methods. It also opens the possibility to use variable assignment as a means to handle nodes (by overriding setProperty), a fact that JsonGroovyBuilder exploits to let you code JSON in a 99% identical way, just replace '=' for ':' and see for yourself
I guess that with the recent additions to the MetaClass system some of the internals of these builders may be revised.

Keep on Groovying!
Andres Almiray

About Andres Almiray

Andres is a Java/Groovy developer and a Java Champion with more than 20 years of experience in software design and development. He has been involved in web and desktop application development since the early days of Java. Andres is a true believer in open source and has participated on popular projects like Groovy, Griffon, and DbUnit, as well as starting his own projects (Json-lib, EZMorph, GraphicsBuilder, JideBuilder). Founding member of the Griffon framework and Hackergarten community event. https://ch.linkedin.com/in/aalmiray

Why Attend the NFJS Tour?

  • » Cutting-Edge Technologies
  • » Agile Practices
  • » Peer Exchange

Current Topics:

  • Languages on the JVM: Scala, Groovy, Clojure
  • Enterprise Java
  • Core Java, Java 8
  • Agility
  • Testing: Geb, Spock, Easyb
  • REST
  • NoSQL: MongoDB, Cassandra
  • Hadoop
  • Spring 4
  • Cloud
  • Automation Tools: Gradle, Git, Jenkins, Sonar
  • HTML5, CSS3, AngularJS, jQuery, Usability
  • Mobile Apps - iPhone and Android
  • More...
Learn More »