
- •brief contents
- •contents
- •foreword
- •preface
- •acknowledgments
- •about this book
- •Roadmap
- •Code conventions and downloads
- •Author Online
- •About the author
- •about the cover illustration
- •1 Why add Groovy to Java?
- •1.1 Issues with Java
- •1.1.1 Is static typing a bug or a feature?
- •1.1.2 Methods must be in a class, even if you don’t need or want one
- •1.1.3 Java is overly verbose
- •1.1.4 Groovy makes testing Java much easier
- •1.1.5 Groovy tools simplify your build
- •1.2 Groovy features that help Java
- •1.3 Java use cases and how Groovy helps
- •1.3.1 Spring framework support for Groovy
- •1.3.2 Simplified database access
- •1.3.3 Building and accessing web services
- •1.3.4 Web application enhancements
- •1.4 Summary
- •2 Groovy by example
- •2.1 Hello, Groovy
- •2.2 Accessing Google Chart Tools
- •2.2.1 Assembling the URL with query string
- •2.2.2 Transmitting the URL
- •2.2.3 Creating a UI with SwingBuilder
- •2.3 Groovy Baseball
- •2.3.1 Database data and Plain Old Groovy Objects
- •2.3.2 Parsing XML
- •2.3.3 HTML builders and groovlets
- •2.4 Summary
- •3 Code-level integration
- •3.1 Integrating Java with other languages
- •3.2 Executing Groovy scripts from Java
- •3.2.1 Using JSR223 scripting for the Java Platform API
- •3.2.2 Working with the Groovy Eval class
- •3.2.3 Working with the GroovyShell class
- •3.2.4 Calling Groovy from Java the easy way
- •3.2.5 Calling Java from Groovy
- •3.3 Summary
- •4 Using Groovy features in Java
- •4.1 Treating POJOs like POGOs
- •4.2 Implementing operator overloading in Java
- •4.3 Making Java library classes better: the Groovy JDK
- •4.4 Cool AST transformations
- •4.4.1 Delegating to contained objects
- •4.4.2 Creating immutable objects
- •4.4.3 Creating singletons
- •4.5 Working with XML
- •4.6 Working with JSON data
- •4.7 Summary
- •5 Build processes
- •5.1 The build challenge
- •5.2 The Java approach, part 1: Ant
- •5.3 Making Ant Groovy
- •5.3.1 The <groovy> Ant task
- •5.3.2 The <groovyc> Ant task
- •5.3.3 Writing your build in Groovy with AntBuilder
- •5.3.4 Custom build scripts with Gant
- •5.3.5 Ant summary
- •5.4 The Java approach, part 2: Maven
- •5.4.2 The GMaven project
- •5.4.3 Maven summary
- •5.5 Grapes and @Grab
- •5.6 The Gradle build system
- •5.6.1 Basic Gradle builds
- •5.6.2 Interesting configurations
- •5.7 Summary
- •6 Testing Groovy and Java projects
- •6.1 Working with JUnit
- •6.1.1 A Java test for the Groovy implementation
- •6.1.2 A Groovy test for the Java implementation
- •6.1.3 A GroovyTestCase test for a Java implementation
- •6.2 Testing scripts written in Groovy
- •6.2.1 Useful subclasses of GroovyTestCase: GroovyShellTestCase
- •6.2.2 Useful subclasses of GroovyTestCase: GroovyLogTestCase
- •6.3 Testing classes in isolation
- •6.3.1 Coerced closures
- •6.3.2 The Expando class
- •6.3.3 StubFor and MockFor
- •6.4 The future of testing: Spock
- •6.4.1 The Search for Spock
- •6.4.2 Test well, and prosper
- •6.4.4 The trouble with tribbles
- •6.4.5 Other Spock capabilities
- •6.5 Summary
- •7 The Spring framework
- •7.1 A Spring application
- •7.2 Refreshable beans
- •7.3 Spring AOP with Groovy beans
- •7.4 Inline scripted beans
- •7.5 Groovy with JavaConfig
- •7.6 Building beans with the Grails BeanBuilder
- •7.7 Summary
- •8 Database access
- •8.1 The Java approach, part 1: JDBC
- •8.2 The Groovy approach, part 1: groovy.sql.Sql
- •8.3 The Java approach, part 2: Hibernate and JPA
- •8.4 The Groovy approach, part 2: Groovy and GORM
- •8.4.1 Groovy simplifications
- •8.5 Groovy and NoSQL databases
- •8.5.1 Populating Groovy vampires
- •8.5.2 Querying and mapping MongoDB data
- •8.6 Summary
- •9 RESTful web services
- •9.1 The REST architecture
- •9.3 Implementing JAX-RS with Groovy
- •9.4 RESTful Clients
- •9.5 Hypermedia
- •9.5.1 A simple example: Rotten Tomatoes
- •9.5.2 Adding transitional links
- •9.5.3 Adding structural links
- •9.5.4 Using a JsonBuilder to control the output
- •9.6 Other Groovy approaches
- •9.6.1 Groovlets
- •9.6.2 Ratpack
- •9.6.3 Grails and REST
- •9.7 Summary
- •10 Building and testing web applications
- •10.1 Groovy servlets and ServletCategory
- •10.2 Easy server-side development with groovlets
- •10.2.1 A “Hello, World!” groovlet
- •10.2.2 Implicit variables in groovlets
- •10.3.2 Integration testing with Gradle
- •10.3.3 Automating Jetty in the Gradle build
- •10.4 Grails: the Groovy “killer app”
- •10.4.1 The quest for the holy Grails
- •10.5 Summary
- •A.1 Installing a JDK
- •A.2 Installing Groovy
- •A.3 Testing your installation
- •A.4 IDE support
- •A.5 Installing other projects in the Groovy ecosystem
- •B.1 Scripts and the traditional example
- •B.2 Variables, numbers, and strings
- •B.2.1 Numbers
- •B.2.2 Strings and Groovy strings
- •B.3 Plain Old Groovy Objects
- •B.4 Collections
- •B.4.1 Ranges
- •B.4.2 Lists
- •B.4.3 Maps
- •B.5 Closures
- •B.6 Loops and conditionals
- •B.6.1 Loops
- •B.6.2 Conditionals
- •B.6.3 Elvis
- •B.6.4 Safe de-reference
- •B.7 File I/O
- •B.8.1 Parsing and slurping XML
- •B.8.2 Generating XML
- •B.8.3 Validation
- •B.9 JSON support
- •B.9.1 Slurping JSON
- •B.9.2 Building JSON
- •index
- •Symbols

Accessing Google Chart Tools |
23 |
The result of all this manipulation is actually a string, not a URL. Before converting it to a URL, let me first verify that the process worked. Normally this would require a test, as discussed extensively in chapter 6 on testing. Here, however, I’ll just use the Groovy assert keyword, which takes a boolean expression as an argument. If the expression is true, nothing is returned, but if not, you get the error printed to the console. In this case I’ll use the contains method from the Map interface to check that each of the entries from the params map appears in the query string in the proper format:
params.each { k,v ->
assert qs.contains("$k=$v")
}
THE ASSERT KEYWORD Groovy asserts are an easy way to verify correctness. An assert returns nothing if the expression is true, and prints a detailed error message if it’s not.
One of the advantages of the join method is that you don’t have to worry about accidentally adding an ampersand at the beginning or end of the string. It only adds the separator internally.
Note also that this is a case where the parentheses (on the join method) are needed. In Groovy, if you leave off the parentheses when calling a method with no arguments the compiler assumes you are asking for the corresponding getter or setter method. Because I want the join() method (and not getJoin(), which doesn’t exist), I need the parentheses.
2.2.2Transmitting the URL
The Groovy JDK adds the toURL() method to the String class. As you might imagine, this method converts an instance of java.lang.String into an instance of java.net.URL.
The Groovy JDK
Groovy adds many helpful methods to existing Java library classes. Many, many times I’ve found methods added to, say, String, Date, or Collection that I always wished were in Java all along. The set of methods added by Groovy is known as the Groovy JDK and has its own set of JavaDocs. The Groovy JDK documentation is available via a link from the Groovy home page.
The Groovy JDK is discussed in more detail in chapter 3.
To send an HTTP GET request to a URL and retrieve the results, convert the string to a URL and invoke another Groovy JDK method, the getText() method, added to java.net.URL. In other words, the data on a web page can be retrieved from this code:
url.toURL().text
www.it-ebooks.info

24 CHAPTER 2 Groovy by example
Here I’m deliberately using the text property of the URL class, knowing that the effect will be to invoke the getText() method. There’s nothing wrong with actually calling getText, but this is more idiomatic Groovy.
Normally this would be exactly the code I want, and I use this technique in some of the examples in the chapters on web services, but in this particular case the result isn’t text. Google Chart takes the URL generated here and returns a binary image, so converting it to text isn’t very helpful.
GROOVY PROPERTIES Accessing properties in Groovy automatically invokes the associated getter or setter method.
Next I’ll build a Swing user interface that includes the image in a javax.swing
.ImageIcon. This will give me a chance to illustrate a builder, which is a great illustration of Groovy metaprogramming.
2.2.3Creating a UI with SwingBuilder
In Groovy every class has a metaclass. A metaclass is another class that manages the actual invocation process. If you invoke a method on a class that doesn’t exist, the call is ultimately intercepted by a method in the metaclass called methodMissing. Likewise, accessing a property that doesn’t exist eventually calls propertyMissing in the metaclass. Customizing the behavior of methodMissing and propertyMissing is the heart of Groovy runtime metaprogramming.
Groovy metaprogramming is a large subject, but here I’ll demonstrate one of its helpful results: the creation of builder classes. In a builder, the call to methodMissing does something specific for that type of builder.
Here I’ll illustrate a Swing builder. This is a class that intercepts names of components and constructs a Swing user interface out of the results. This is actually easier to demonstrate than to explain. I’ll start, however, by adding some imports to the Google Chart script I’ve been constructing so far:3
import java.awt.BorderLayout as BL import javax.swing.WindowConstants as WC import groovy.swing.SwingBuilder
import javax.swing.ImageIcon
Automatic imports
You may have noticed that I haven’t yet needed any import statements at all. Java automatically imports the java.lang package. Groovy imports java.lang, as well as java.util, java.io, java.net, groovy.lang, groovy.util, java.math.BigInteger, and java.math.BigDecimal.3
3That’s another one of the “Duh! Why didn’t we do that all along?” type of revelations that Java developers get all the time when they first learn Groovy. Why is it we only import java.lang in Java programs? Why not import lots of typical packages? Wouldn’t that make coding easier? Groovy says yes.
www.it-ebooks.info
Accessing Google Chart Tools |
25 |
In this script I’m importing three classes from the Java standard library. The first two imports use the as operator to build an alias for the respective classes. That way the code that uses BorderLayout and WindowConstants can just write BL or WC instead. I’m also adding in the ImageIcon class, which will hold the image returned by Google Chart. The import from the Groovy library is SwingBuilder, which will be used to construct the Swing UI.
THE AS KEYWORD The as keyword has several uses, one of which is to provide an alias for imported classes. The as keyword corresponds to the asType method, which was added to java.lang.Object as part of the Groovy JDK.
In the case of SwingBuilder you invoke methods that don’t exist on the builder but that are translated to the corresponding Swing API. For example, by calling the frame method you’re actually instantiating the JFrame class. Giving it a map-like argument of visible:true corresponds to calling the setVisible method with a true argument.
Here’s the code that uses the builder. Each method not in SwingBuilder is translated to the proper method call on the Swing library class:
SwingBuilder.edt {
frame(title:'Hello, World!', visible:true, pack: true, defaultCloseOperation:WC.EXIT_ON_CLOSE) {
label(icon:new ImageIcon("$base$qs".toURL()), constraints:BL.CENTER)
}
}
The edt method on SwingBuilder builds a GUI using the event dispatch thread. It takes a closure as an argument, and this is where the fun starts. The first statement inside the closure is a call to the frame method, but the fact is, there’s no frame method in SwingBuilder. The builder’s metaclass intercepts that call (via methodMissing) and interprets it as a request to instantiate the javax.swing.JFrame class. The frame method here lists a series of map entries, which are intended to supply values for the title, visibility, and close operation on the JFrame. The builder interprets them as calls to setTitle, setVisible, and setDefaultCloseOperation on the
JFrame instance.
After the parentheses there’s another closure. That’s interpreted to mean I’m about to supply components that will be added to the JFrame instance. The next call is to the label method, which of course doesn’t exist. The Swing builder knows to generate a JLabel instance as a result, call its setIcon method with a new ImageIcon holding the image returned by Google Chart, and place the JLabel in the center of a
BorderLayout.
Finally, after the frame closure I invoke the pack method on JFrame to make the resulting GUI just big enough to hold the image. The next listing contains the complete script (without the asserts, just to keep the listing short).
www.it-ebooks.info