Groovy for Domain-Specific Languages
The Java virtual machine runs on everything from the largest mainframe to the smallest
microchip and supports every conceivable application. But Java is a complex and
sometimes arcane language to develop with. Groovy allows us to build targeted singlepurpose
minilanguages, which can run directly on the JVM alongside regular Java code.
This book provides a comprehensive tutorial on designing and developing miniGroovybased
Domain-Specific Languages. It is a complete guide to the development of several
miniDSLs with a lot of easy-to-understand examples. This book will help you to gain all
of the skills needed to develop your own Groovy-based DSLs.
Groovy for Domain-Specific Languages guides the reader from the basics through to the
more complex meta-programming features of Groovy. The focus is on how the Groovy
language can be used to construct domain-specific minilanguages. Practical examples are
used throughout to demystify these seemingly complex language features and to show
how they can be used to create simple and elegant DSLs. The examples include a quick
and simple Groovy DSL to interface with Twitter.
The book concludes with a chapter focusing on integrating Groovy-based DSL in such a
way that the scripts can be readily incorporated into the reader’s own Java applications.
The overall goal of this book is to take Java developers through the skills and knowledge
they need to start building effective Groovy-based DSLs to integrate into their
own applications.
- Buy Groovy Books in Java Books Store
What This Book Covers
Chapter 1, Introduction to DSL and Groovy, discusses how DSLs can be used in place of
general-purpose languages to represent different parts of a system. You will see how
adding DSLs to your applications can open up the development process to other
stakeholders in the development process. You’ll also see how, in extreme cases, the
stakeholders themselves can even become co-developers of the system by using DSLs
that let them represent their domain expertise in code.
Chapter 2, Groovy Quick Start, covers a whistle-stop tour of the Groovy language. It also
touches on most of the significant features of the language as a part of this tour.
Chapter 3, Groovy Closures, covers closures in some depth. It covers all of the important
aspects of working with closures. You can explore the various ways to call a closure and
the means of passing parameters. You will see how to pass closures as parameters to
methods, and how this construct can allow us to add miniDSL syntax to our code.
Chapter 4, Example DSL: GeeTwitter, focuses on how we can start with an existing Javabased
APiand evolve it into a simple user-friendly DSL that can be used by almost
anybody. You’ll learn the importance of removing boilerplate code and how you can
structure our DSL in such a way that the boilerplate is invisible to our DSL users.
Chapter 5, Power Groovy DSL Features, covers all of the important features of the
Groovy language, and looks in depth at how some of these features can be applied to
developing DSLs.
Chapter 6, Existing Groovy DSLs, discusses some existing Groovy DSLs that are in
current use and are free to download.
Chapter 7, Building a Builder, explains how Groovy provides two useful support classes
that make it much simpler to implement our own builders than if we use the MOP. You’ll
see how to use BuilderSupport and FactoryBuilderSupport to create our own
builder classes.
Chapter 8, Implementing a Rules DSL, takes a look at Groovy bindings to see how they
can be used in our DSL scripts. By placing closures strategically in the binding, you can
emulate named blocks of code. You can also provide built-in methods and other
shorthand by including closures and named Boolean values in the binding. These
techniques can be used to a great effect to write DSL scripts that can be read and
understood by stakeholders outside of the programming audience.
Chapter 9, Integrating it all, covers the many different ways in which you can integrate
Groovy code into Java. You’ll explore the issues around tightly integrating the two
languages at compile time. You’ll see how this can lead to dependency issues arising
when Java code references Groovy classes and vice versa. You’ll take a look at how you
can use dependency injection frameworks like Spring to resolve some of these issues.
Building a Builder
Builders are a powerful feature of Groovy. The Groovy libraries contain an
expanding set of Builders for everything from XML and HTML markup to managing
systems via JMX. Even so you will always come across circumstances where the
semantics of a builder would be useful in your own application.
We’ve seen how to build a rudimentary builder by using the Groovy MOP and
pretended methods in Chapter 5. Thankfully, the Groovy libraries provide us with
easier means of developing our own builders. In this chapter, we will look at some of
the ways in which we can use Groovy and the MOP to create our own builder classes.
- To begin with, we will recap the Groovy features that enable the Groovy
builder pattern in order to understand how they work. - We will look at how to build a rudimentary builder with features from the
Groovy MOP. - We will implement our own database seed data Builder by using two of
the builder support classes provided in Groovy: BuilderSupport and
FactoryBuilderSupport.
Builder code structure
The real beauty of Groovy‘s builder paradigm is the way in which it maps the
naturally nested block structure of the language to the construction process.
The process of defining parent-child relationships between objects through nested
code blocks is well-established through other markup languages, such as
XML and HTML.
The transition from writing XML or HTML to the GroovyMarkup equivalent
is an easy one. To make use of a builder, we don’t need to have any intimate
understanding of the Groovy MOP or of how the builder is implemented. We
just need to know how to write the builder code so that it conforms to the correct
language semantics. The code structure of the builder pattern relies on just a few
Groovy language features.
- Closure method calls: The distinctively nested block structure in the builder
pattern is facilitated by Groovy‘s special handling of closures when they are
passed as method parameters. This allows the closure block to be declared
inline after the other method call parameters. - Closure method resolution: When a method is invoked within the body of a
closure and that method does not exist in the closure instance, Groovy uses
a resolve strategy to determine which object (if any) should be tried to locate
that method. - Pretended methods: The Groovy MOP allows us to respond to method
calls that do not exist in a class—in other words to “pretend” that these
methods exist. - Named parameters: When we pass a map parameter to a method, we can
declare the individual map elements alongside the other method parameters,
giving the effect of a named parameter list. - Closure delegate: Changing the delegate of a closure allows another class to
handle its method calls. When we change the delegate to a builder class, this
allows the builder to orchestrate how the method calls are handled.
Closure method calls
When we declare a Groovy method that accepts a closure as its last parameter,
Groovy allows us to define the body of the inline closure immediately after the
method call containing the other parameters. A method call followed by an inline
closure block has all the appearance of being a named block of code. It’s when we
nest these method calls within each other that we get the distinctive builder-style
code blocks.
This style of coding is not unique to builders. We can nest other method calls in
the same way. In the following example, we have three methods defined within a
script: method1(), method2(), and method3(). Nesting calls to these methods gives us
some code that is very similar to a builder block, but is not actually a builder block.
The cool thing about the builder pattern is that it uses this existing feature from the
language and turns it into a whole new coding paradigm.

The success of building our own b uilder class by using the Groovy MOP depends
largely o n understanding the sequence in which these methods get called. The
output gives us an idea of what might be happening and what the true sequence of
events is. Let’s decorate the code a little to show what is happening. The comments
show what scope we are running in.
// Script scope
method1(param: “one”) { // Closure1 scope
method2 { // Closure2 scope
method3 “hello”
} // End Closure2
method1( 123 ) { // Closure3 scope
method1 ( “nested” ) { // Closure4 scope
method3 10
} // End Closure4
} // End Closure3
} // End Closure1
The main block of code runs within the scope of the script. Each inline closure is in
fact an anonymous instance of a C losure object. For the purpose of this exercise we
will name these instances Closure1 to Closure4. The first call to m ethod1() occurs
in the outer scope of the script so we would expect this method to be passed to the
script instance. The subsequent method calls all happen within the scope of one or
other of the anonymous closure instances, so we expect these methods to be invoked
on the individual closure instances. The following sequence diagram illustrates this:

Resolve Strategy: OWNER_FIRST
The one problem with the previous diagram is that we know that the closure
instances don’t implement the method1() t o method3() methods. So this sequence
diagram shows what methods are initially called, but it does not show what methods
actually get called. When Groovy makes a call to a method on a closure, it does not
always expect it to be present.
If a method is not present in the closure itself, Groovy will try to find it by looking
in the owner of the closure, or its delegate, or both. The order in which this occurs
is called the resolve strategy of the closure. The default resolve strategy is OWNER_
FIRST, which means that the owner of the closure will be queried first for the
method, followed by the delegate. If the owner of the closure happens to be another
closure, then the resolve strategy will continue its search for a match in the owner of
the owner and so on, until a match is found or the outer scope is reached.
The resolve strategy can be changed for a closure by calling
Closure.setResolveStrategy. We can change the resolve strategy to
any of the following self-explanatory strategies: OWNER_FIRST, OWNER_
ONLY, DELEGATE_FIRST, DELEGATE_ONLY, and NONE.
Although the preceding sequence diagram refl ects the first port of call for e ach
method invocation, what in fact happens is that the resolve strategy kicks in and
the method calls will percolate out through the closure instances. A match will
eventually be found in the script instance, which is the only place where the actual
methods exist. Therefore, the actual calling sequence is better represented as follows:

The insight that Groovy designers had when designing the builder pattern was that
this natural nesting of closures could be used to map to any construction process that
involved a parent-child type of relationship. Even without using a builder class, we
can nest closures’ method calls to create a pseudo builder. In the next example, we
declare three methods that we can use to construct a rudimentary tree structure out
of map objects.
The root() method creates the initial tree map and inserts a root element into it. We
can nest as many levels deep as we like with the nod e() method, as it will remember
its parent node and add sub nodes to it. The leaf() method is the only one to take a
value and it does not expect to be passed a closure, as it will create the leaf elements
in the tree structure.
def current
def root (Closure closure) {
def tree = [:]
def root = [:]
tree["root"] = root
def parent = current
current = root
closure.call()
current = parent
return tree
}
def node (key, Closure closure) {
def node = [:]
current[key] = node
def parent = current
current = node
closure.call()
current = parent
}
def leaf (key, value ) {
current[key] = value
}
// pseudo builder code
def tree = root {
node (“sub-tree-1″) {
leaf “leaf-1″, “leaf object 1″
}
node (“sub-tree-2″){
node (“node-1″){
leaf “leaf-2″, “leaf object 2″
}
}
}
assert tree == [
root: [
"sub-tree-1": [
"leaf-1": "leaf object 1"
],
“sub-tree-2″: [
"node-1": [
"leaf-2": "leaf object 2"
]
]
]
]
Pretended methods
Many Groovy builders rely on the ability to describe arbitrarily-named elements.
When we make use of markup builders to generate XML, we need to be able to
insert whatever tag names are required to conform to the schema that we are using.
Given that elements are created in method calls, we also need to be able to make
arbitrarily- named method calls during the markup process.
With Groovy, we can respond to methods that don’t exist as concrete methods of
a class. The term we use for this type of methods is pretended methods. Groovy
provides two means for implementing a pretended method.
invokeMethod
The PoorMansTagBuilder class that we covered in Chapter 5 uses invokeMethod as
a means of pretending methods. The Poo rMansTagBuilder class works by handling
all method calls to the builder, and invoking the closure argument manually. With
invokeMethod, we can respond appropriately to any arbitrary method call. In this
case, we output the appropriate XML tags.
class PoorMansTagBuilder {
int indent = 0
Object invokeMethod(String name, Object args) {
indent.times {print ” “}
println “<${name}>”
indent++
args[0].delegate = this // Change delegate to the builder
args[0].call()
indent–
indent.times {print ” “}
println “</${name}>”
}
}
This is a simple case that we are using just to illustrate the mechanism. Although the
technique works for simple cases, extending it to implement a more complete
tag builder would rapidly result in complex and hard-to-maintain code.
methodMissing
Since Groovy 1.5, an alternative to invokeMethod was provided. The
methodMissing mechanism differs slightly from invokeMethod, as it is only called
when a method call fails to be dispatched to any concrete method. To update the
PoorMansTagBuilder for using methodMissing instead of invokeMethod, all we
need to do is replace the method name that we declare.
class PoorMansTagBuilder {
int indent = 0
def methodMissing(String name, args) {
indent.times {print ” “}
println “<${name}>”
indent++
args[0].delegate = this // Change delegate to the builder
args[0].call()
indent–
indent.times {print ” “}
println “</${name}>”
}
}
def builder = new PoorMansTagBuilder ()
builder.root {
level1{
level2 {
}
}
}
Closure delegate
Earlier, we looked at how to code a pseudo builder using, methods declared within
a script. The resolve strategy in that example passed method calls in the nested
closure up to the owner of the closure. The builder block in the previous example is
also in the scope of a script. Let’s decorate it as we did before, to identify the various
anonymous closure instances.
// method root() called on PoorMansTagBuilder
builder.root { // Closure1
// method level1 called on Closure1 instance
level1{ // Closure2
// method level2 called on Closure2 instance
level2 { // Closure3
}
}
}
The first method call to root() is made against the builder instance, so it will be
handled directly by Poo rMansTagBuilder.methodMissing(). Nested method
calls will first be dispatched to the enclosing closure. The lev el1() and lev el2()
methods won’t be found in the closure instances, so we would normally expect the
resolve strategy to dispatch these methods up the chain of owners until a method
is found. This normal dispatch chain would end up at the script instance, so these
methods would cause a MethodMissingException to be thrown.
The secret of how this works is in the handling of the delegate for closure instances.
The builder block starts with a direct method call onto the builder instance, builder.
root(). Anonymous closure, Closure1, is passed as a par ameter. The call to root()
will fail and fall through to methodMissing. In this simple example, arg[0] is
always the closure because we are not processing parameters on our tags. A more
sophisticated version would need to scan the parameters for the closure instance.
At this point we have access to the closure, so we can set its delegate to the builder
instance. Now when the level1() and level2() calls are encountered, the resolve
strategy will try the owner first and then try the delegate as follows:
- The level1() call will not be resolved in Closure1. It won’t be found
in the owner of Closure1, which is the script, but it will be resolved in
the delegate,which is the builder instance. PoorMansTagBuilder.
methodMissing will field the method and also set the delegate for the
anonymous closure, Closure2. - The level2() call ha ppens in the scope of Closure2 but will not be resolved
there. First its owner, Closure1, will be tried, and then its delegate, which
once again is the builder instance.
Groovy Articles
- Buy Groovy Books in Java Books Store
- Introduction to Groovy – Scripting Language
- Groovy Articles
- Closures in Groovy
- Web Development in Groovy using Groovlets






October 8, 2010
Groovy